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 ワープ内の分岐分岐にあります。ワープ内のすべてのスレッドが同じ命令を同時に実行するため、一部のスレッドが 1 つの分岐を取り、残りのスレッドが別の分岐を取る場合、時間は 2 倍になります。ただし、それはワープ内の問題にすぎません。したがって、同じワープ内のすべてのスレッドが 1 つの分岐を取り、別のワープ内のすべてのスレッドが別の分岐を取る場合、パフォーマンスへの影響はありません。

ワープとは何かがわからない場合は、CUDA スレッド モデルに関する古い記事ですが、これはまだ良い記事です: http://www.pgroup.com/lit/articles/insider/v2n1a5.htm

このコードでは、最後の要素だけが真のケースを取るため、if ステートメントの影響はほとんどありません。

最後の要素のケースがelse句になるように、ロジックを反転することをお勧めします。これは一般的な最適化であり、GPU に固有のものではないため、より一般的なケースではジャンプする必要がなくなります。

于 2016-08-11T19:44:44.777 に答える