我听说OpenACC不能有效地处理if语句,应该尽量避免使用它。
例如,在device/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语句呢?
发布于 2016-08-12 03:44:45
问题在于CUDA翘曲中的分支发散。由于warp中的所有线程都同时执行相同的指令,因此如果一些线程采用一个分支,而其他线程采用另一个分支,那么您的时间就加倍了。然而,这只是一个曲折中的问题。因此,如果同一条经线中的所有线程采用一个分支,而另一条经线中的所有线程采用不同的分支,则不会对性能产生影响。
如果你不知道什么是偏差,这是一篇关于CUDA线程模型的古老但仍然很好的文章:http://www.pgroup.com/lit/articles/insider/v2n1a5.htm
在这段代码中,由于只有最后一个元素接受true case,所以if语句的影响很小。
我建议颠倒您的逻辑,这样最后一个元素的大小写就在else子句中。这是一种不特定于GPU的通用优化,因此更常见的情况会失败,而不是必须进行跳跃。
https://stackoverflow.com/questions/38904292
复制相似问题