1

我听说 OpenACC 不能有效地处理 if 语句,应该尽量避免使用它。

例如,在设备/OpenACC 中做这样的事情(带有几个 if 语句的循环)是不好的:

for (m=0; m<polygon2.num_vertices; m++) {

    polygon2Vertex1 = listOfpolygon2Vertex[m];

    if ((m+1) == polygon2.num_vertices){
        // last vertex, so we get last and the first vertex
        polygon2Vertex2 = listOfpolygon2Vertex[0];

    } else {
        // not the last vertex, so we get [m] and [m+1] vertex
        polygon2Vertex2 = listOfpolygon2Vertex[m+1];
    }

    result = doIntersect(polygon1Vertex1, polygon1Vertex2, polygon2Vertex1, polygon2Vertex2);

    if (result==1){
        // found that these 2 edges intersect.
        // no need to further check

        break;
    }
}

是真的吗?如果是这样,我该如何处理 OpenACC 中的 if 语句?

4

1 回答 1

1

问题在于 CUDA 扭曲中的分支分歧。由于 warp 中的所有线程同时执行相同的指令,如果一些线程采用一个分支而其余线程采用另一个分支,则您的时间增加了一倍。然而,这只是扭曲中的一个问题。因此,如果同一个 warp 中的所有线程都采用一个分支,而另一个 warp 中的所有线程都采用不同的分支,则不会对性能产生影响。

如果您不知道什么是扭曲,请参阅关于 CUDA 线程模型的旧但仍然不错的文章:http ://www.pgroup.com/lit/articles/insider/v2n1a5.htm

使用此代码,由于只有最后一个元素采用 true 大小写,因此 if 语句的影响很小。

我建议颠倒您的逻辑,以便最后一个元素案例在 else 子句中。这是一种非特定于 GPU 的一般优化,因此更常见的情况会通过而不是必须进行跳转。

于 2016-08-11T19:44:44.777 回答