DirectX - página 3

 
Rorschach:

¡Muchas gracias!

¿Sus cálculos son dobles? Entonces el resultado es particularmente impresionante.

Buen punto. De hecho, en un lugar era float en lugar de double:

D = fast_length(p);

Para que sea doble, tenemos que corregirlo a

D = length(p);

Además, puede deshacerse de la última línea (análoga a la macro XRGB) aplicando uchar4 en lugar de uint para el argumento *buf. Inténtalo así:

__kernel void Func(int N, __global double *XP, __global double *YP, __global uchar *h, __global uchar4 *buf)
{
   size_t X = get_global_id(0);
   size_t Width = get_global_size(0);
   size_t Y = get_global_id(1);
   
   float2 p;
   double D=0,S1=0,S2=0;
   
   for(int w=0;w<N;w++){ 
      p.x = XP[w]-X;
      p.y = YP[w]-Y;
      D = length(p);
      S2+=D;
      if(w<N/2)
         S1+=D;
   }   
   //
   double d=S1/S2;
   buf[Y*Width+X] = (uchar4)(0xFF,h[(int)(d*11520)],h[(int)(d*17920)],h[(int)(d*6400)]);
}
 
Serhii Shevchuk:

Es realmente impresionante. Los Fps son 1,5 veces más altos que con los shaders.

Gracias, el código funciona, no hay degradación del rendimiento, sólo he movido el canal alfa al final en la última línea:

buf[Y*Width+X] = (uchar4)(h[(int)(d*11520)],h[(int)(d*17920)],h[(int)(d*6400)],0xFF);
 
Rorschach:

Es realmente impresionante. Los Fps son 1,5 veces más altos que con los shaders.

Gracias, el código funciona, el rendimiento no se degrada, sólo en la última línea el canal alfa se trasladó al final:

En esta aplicación, el rendimiento depende en gran medida del número de centros (N). Lo ideal sería deshacerse del bucle en el núcleo, pero en este caso tendremos que hacer que S1 y S2 sean enteros. Habrá que ver cómo de grande es la dispersión de sus valores y quizás podamos multiplicarlos por algo sin pecar demasiado. Y entonces es posible transferir el bucle a la tercera dimensión, lo que teóricamente dará una ganancia de rendimiento en valores altos de N.

Consigo 80-90 fps en mi HD 7950 en un monitor full-hd a N=128.

 
Serhii Shevchuk:

En esta aplicación, el rendimiento depende en gran medida del número de centros (N). Sería bueno deshacerse del bucle en el núcleo, pero entonces S1 y S2 tendrían que ser enteros. Habrá que ver cómo de grande es la dispersión de sus valores y quizás podamos multiplicarlos por algo sin pecar demasiado. Y entonces es posible transferir un bucle a la tercera dimensión, que teóricamente dará una ganancia de rendimiento en valores altos de N.

Consigo 80-90 fps en mi HD 7950 en un monitor full-hd a N=128.

Mi 750ti tiene 11 fps. He encontrado las especificaciones de las tarjetas:

GPU
FP32 GFLOPS
FP64 GFLOPS Ratio
Radeon HD 7950 2867 717 FP64 = 1/4 FP32
GeForce GTX 750 Ti 1388 43 FP64 = 1/32 FP32

Lógicamente, cambiar a float puede aumentar los fps en un factor de 4 en amd y 32 en nvidia.

 

Hice una copia de la versión OCL. Estoy sorprendido por el resultado. En los centros de 1600 no podía cargar la vidia más del 85%.

La optimización con h precalculada no tiene ningún efecto, pero se deja. Todos los cálculos están en float, no veo el sentido de usar double ya que todas las funciones devuelven float de todos modos.

Archivos adjuntos:
pixel.zip  1 kb
 

Algunas conclusiones.

1) El cálculo previo de h no tuvo ningún efecto.

2) No he notado ninguna diferencia al deshacerme de si.

S1+=D*(i<0.5 f*N);
//if(i<N*0.5 f) S1+=D;

3) Es más lento,

for(int i=0;i<N;i++)
  {XP[i]= (1.f-sin(j/iArr[2*i  ].w))*wh.x*0.5 f;
   YP[i]= (1.f-cos(j/iArr[2*i+1].w))*wh.y*0.5 f;
  }
float S1=0.f,S2=0.f;
for(int i=0;i<N;i++)
  {float2 p;
   p.x=XP[i]-Pos.x;
   p.y=YP[i]-Pos.y;
   ...
  }

que el

float S1=0.f,S2=0.f;
for(int i=0;i<N;i++)
  {float2 p;
   p.x=(1.f-sin(j/iArr[2*i  ].w))*wh.x*0.5 f-Pos.x;
   p.y=(1.f-cos(j/iArr[2*i+1].w))*wh.y*0.5 f-Pos.y;
   ...
  }

parece que...

4) No se puede descargar la CPU, es decir, se pueden olvidar las pilas de los revendedores, etc.

 
Rorschach:

Algunas conclusiones.

1) El cálculo previo de h no tuvo ningún efecto.

2) No he notado ninguna diferencia al deshacerme de si.

3) Es más lento,

que el

parece que...

4) No se puede descargar la CPU, es decir, se pueden olvidar las pilas de los revendedores, etc.

En MT5, los stacks de scalpers pueden ejecutarse fácilmente en un hilo sin OCL y no sobrecargar la CPU. Por supuesto, esto no significa que no sea necesario. Sólo una información.

Si utiliza la clase CCanvas al construir un parteluz, la carga de trabajo será proporcional al tamaño del parteluz. Es decir, cuanto más grande sea la ventana en el mull, más pesada será la carga, porque se está redibujando todo el lienzo, no las partes individuales modificadas. Sin embargo, al convertir las celdas de los vasos en elementos independientes, pueden actualizarse independientemente del resto del área del kanvas, lo que reduce varias veces el tiempo de redibujado y la carga que éste supone para el procesador.

 
Реter Konow:

En MT5, las pilas de scalpers pueden ejecutarse fácilmente en un solo hilo, sin OCL y sin sobrecargar la CPU. Por supuesto, eso no significa que no sea necesario. Sólo una información.

Si utiliza la clase CCanvas al construir un parteluz, la carga de trabajo será proporcional al área del parteluz. Es decir, cuanto más grande sea la ventana en el mull, mayor será la carga, porque es TODO el lienzo, no sólo algunas partes modificadas, lo que se redibuja. Sin embargo, al convertir las celdas de los vasos en elementos independientes, pueden actualizarse independientemente del resto del área del kanvas, lo que reduce varias veces el tiempo de redibujado y la carga que éste supone para el procesador.

4º punto en cuestión. En el ejemplo de Remnant3D, la CPU apenas está cargada.

 
Rorschach:

El punto 4 está en cuestión. El ejemplo de Remnant3D apenas carga la CPU.

Esto ha sido probado. La CPU en MT5, en caso de dinámica normal del lienzo, casi no se carga, si se redibujan celdas individuales en las que el valor ha cambiado.

Por el contrario, si cada valor entrante se redibuja en toda el área del lienzo, el procesador se estresará mucho.

La diferencia está en el número de valores reiniciados en la matriz de píxeles. Hay que actualizar selectivamente áreas individuales y no tendrás problemas de carga.

 
Реter Konow:

Esto ha sido probado. La CPU en MT5, en caso de dinámica normal del lienzo, casi no se carga, si se redibujan celdas individuales en las que el valor ha cambiado.

Por el contrario, si cada valor entrante se redibuja en toda el área del lienzo, el procesador se estresará mucho.

La diferencia está en el número de valores reiniciados en la matriz de píxeles. Hay que actualizar selectivamente áreas individuales y no tendrás problemas de carga.

Eso es lo que tiene Remnant3D: es un lienzo a pantalla completa y no carga la CPU.