2016-08-11 2 views
1

Ich habe gehört, dass OpenACC if-Anweisung nicht effizient behandelt und sollte versuchen, es zu vermeiden.ist If-Anweisung schlecht für OpenACC?

Zum Beispiel ist es nicht gut (mit ein paar if-Anweisung Schleife) in dem Gerät, so etwas zu tun/OpenACC:

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; 
    } 
} 

ist es wahr? Wenn ja, was kann ich tun, um if-Anweisungen in OpenACC zu behandeln?

Antwort

1

Das Problem ist mit Zweigdivergenzen innerhalb einer CUDA Warp. Da alle Threads in einem Warp denselben Befehl zur selben Zeit ausführen, wenn einige der Threads einen Zweig nehmen und der Rest einen anderen Zweig, haben Sie Ihre Zeit verdoppelt. Es ist jedoch nur ein Problem innerhalb eines Warps. Wenn also alle Threads in demselben Warp einen Zweig nehmen und alle Threads in einem anderen Warp einen anderen Zweig haben, wird es keine Auswirkungen auf die Performance geben.

Wenn Sie nicht wissen, was eine Kette ist, das in der alten, aber immer noch guten Artikel auf dem Modell CUDA Threading: http://www.pgroup.com/lit/articles/insider/v2n1a5.htm

Mit diesem Code, da nur das letzte Element des wahren Fall nimmt, die if-Anweisung wird sehr wenig Einfluss haben.

Ich würde empfehlen, Ihre Logik zu invertieren, so dass der letzte Elementfall in der else-Klausel ist. Dies ist eine allgemeine Optimierung, die nicht für GPUs spezifisch ist, so dass der häufigere Fall durchfällt, anstatt einen Sprung zu machen.