[performance] ¿La divergencia de las ramas es realmente tan mala?


Answers

Question

He visto muchas preguntas dispersas en Internet sobre la divergencia de sucursales y cómo evitarla . Sin embargo, incluso después de leer docenas de artículos sobre cómo funciona CUDA, parece que no veo cómo evitar la divergencia de ramas ayuda en la mayoría de los casos . Antes de que nadie salte sobre mí con las garras extendidas, permítame describir lo que considero que es "la mayoría de los casos".

Me parece que la mayoría de los casos de divergencia de ramas involucran una cantidad de bloques de código verdaderamente distintos. Por ejemplo, tenemos el siguiente escenario:

if (A):
  foo(A)
else:
  bar(B)

Si tenemos dos hilos que encuentran esta divergencia, el hilo 1 se ejecutará primero, tomando el camino A. A continuación, el hilo 2 tomará el camino B. Para eliminar la divergencia, podríamos cambiar el bloque anterior para que se lea así:

foo(A)
bar(B)

Suponiendo que es seguro llamar a foo(A) en el subproceso 2 y la bar(B) en el subproceso 1, se puede esperar que mejore el rendimiento. Sin embargo, así es como lo veo:

En el primer caso, los hilos 1 y 2 se ejecutan en serie. Llamar a estos dos ciclos de reloj.

En el segundo caso, los hilos 1 y 2 ejecutan foo(A) en paralelo, luego ejecutan la bar(B) en paralelo. Esto todavía me parece como dos ciclos de reloj, la diferencia es que en el primer caso, si foo(A) implica una lectura desde la memoria, imagino que el subproceso 2 puede comenzar a ejecutarse durante esa latencia, lo que da como resultado la latencia oculta. Si este es el caso, el código divergente de la sucursal es más rápido.






Links