Aquí hay dos pedazos de código de un kernel de OpenCL en el que estoy trabajando; muestran tiempos de ejecución muy diferentes.OpenCL: ¿Por qué el rendimiento difiere mucho entre estos dos casos?
El código es bastante complicado, por lo que lo he simplificado.
Esta versión se ejecuta en menos de un segundo:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
double nothing = value1;
}
}
y esta versión toma alrededor de 38 segundos para ejecutar:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
Como digo, el código es algo más complicado que esto (hay muchas otras cosas sucediendo en los bucles), pero la variable "nada" realmente se mueve desde inmediatamente antes hasta inmediatamente después del corsé.
Soy nuevo en OpenCL, y no puedo entender qué está pasando, y mucho menos cómo solucionarlo. Huelga decir que el caso lento es realmente lo que necesito en mi implementación. He intentado meterme con los espacios de direcciones (todas las variables aquí están en __private).
Solo puedo imaginar que, por alguna razón, la GPU está presionando la variable "value1" en la memoria más lenta cuando se cierra la abrazadera. ¿Es esta una explicación probable? ¿Que puedo hacer?
¡Gracias de antemano!
ACTUALIZACIÓN: Esto se ejecuta en menos de un segundo también: (pero sin comentario en ninguna de las líneas, vuelve a la lentitud extrema). Esto es sin realizar ningún otro cambio en los bucles, y el valor 1 todavía se declara en el mismo lugar que antes.
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
// value1 = value2 + value3;
// value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
ACTUALIZACIÓN 2: El código fue realmente anidado en otro bucle de este tipo, con la declaración de value1
como se muestra:
double value1=0;
for (int kk=0; kk<someNumber3;kk++)
{
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
en movimiento, donde value1
se declara también nos lleva de nuevo a la caja rápida:
for (int kk=0; kk<someNumber3;kk++)
{
double value1=0;
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
parece OpenCL es un arte muy difícil! Todavía no entiendo realmente lo que está pasando, pero al menos sé cómo solucionarlo ahora.
Eso es bastante extraño. ¿Estás seguro de que necesitas usar la versión más lenta? A partir de estos fragmentos se ven funcionalmente idénticos. – Chriszuma
Gracias por su respuesta. Sí, estoy seguro, pero tienes razón en que los ejemplos que he dado son funcionalmente idénticos. El código en las llaves internas debería tener un + =. – carthurs
No veo ninguna razón para que el segundo sea más lento en función de esos fragmentos de código. Supongo que mover la tarea debe tener efectos secundarios en alguna parte, como una mayor ramificación (una unidad de trabajo ejecuta el 'si', la siguiente ejecuta el' else'), lo que realmente puede ralentizar la GPU. –