我听说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语句?
答案 0 :(得分:1)
问题在于CUDA扭曲中的分支差异。由于warp中的所有线程同时执行相同的指令,如果某些线程占用一个分支而其余线程占用另一个分支,则您的时间会增加一倍。但是,它只是经线内的一个问题。因此,如果同一warp中的所有线程都占用一个分支,而另一个warp中的所有线程占用不同的分支,那么就不会对性能产生影响。
如果您不知道扭曲是什么,请参阅CUDA线程模型的旧文章:http://www.pgroup.com/lit/articles/insider/v2n1a5.htm
使用此代码,由于只有最后一个元素采用了真实的大小写,因此if语句的影响非常小。
我建议反转你的逻辑,以便最后一个元素是在else子句中。这是一个不是特定于GPU的一般优化,因此更常见的情况是通过而不是必须跳转。