DirectX - pagina 3

 
Rorschach:

Grazie mille!

I vostri calcoli sono in doppio? Allora il risultato è particolarmente impressionante.

Buon punto. Infatti, in un posto era float invece di double:

D = fast_length(p);

Per renderlo doppio, dobbiamo correggerlo in

D = length(p);

Inoltre, potete sbarazzarvi dell'ultima linea (analoga alla macro XRGB) applicando uchar4 invece di uint per l'argomento *buf. Prova in questo modo:

__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:

È davvero impressionante! Gli Fps sono 1,5 volte più alti che su shader.

Grazie, il codice funziona, nessuna degradazione delle prestazioni, ho solo spostato il canale alfa alla fine nell'ultima linea:

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

È davvero impressionante! Gli Fps sono 1,5 volte più alti che su shader.

Grazie, il codice funziona, le prestazioni non sono degradate, solo nell'ultima linea il canale alfa è stato spostato alla fine:

In questa implementazione le prestazioni dipendono fortemente dal numero di centri (N). Idealmente dovremmo sbarazzarci del ciclo nel kernel, ma in questo caso dovremo rendere S1 e S2 interi. Dovremo vedere quanto è grande la diffusione dei loro valori e forse potremo moltiplicarli per qualcosa senza troppo peccato. E poi è possibile trasferire il ciclo alla terza dimensione, che teoricamente darà un guadagno di prestazioni ad alti valori di N.

Ottengo 80-90 fps sul mio HD 7950 su monitor full-hd a N=128.

 
Serhii Shevchuk:

In questa implementazione la performance dipende fortemente dal numero di centri (N). Sarebbe bello sbarazzarsi del ciclo nel kernel, ma allora S1 e S2 dovrebbero essere interi. Dovremo vedere quanto è grande la diffusione dei loro valori e forse potremo moltiplicarli per qualcosa senza troppo peccato. E poi è possibile trasferire un ciclo in terza dimensione, che teoricamente darà un guadagno di prestazioni ad alti valori di N.

Ottengo 80-90 fps sul mio HD 7950 su un monitor full-hd a N=128.

La mia 750ti ha 11 fps. Ho trovato le specifiche delle schede:

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

Logicamente, il passaggio a float può aumentare gli fps di un fattore 4 su amd e 32 su nvidia.

 

Fatto una copia della versione OCL. Sono scioccato dal risultato. A 1600 centri non poteva caricare il videoad oltre l'85%.

L'ottimizzazione con h precalcolata non ha alcun effetto, ma è rimasta con essa. Tutti i calcoli sono in float, non vedo il punto di usare il double dato che tutte le funzioni restituiscono comunque float.

File:
pixel.zip  1 kb
 

Alcune conclusioni.

1) Il pre-calcolo di h non ha avuto alcun effetto.

2) Non ho notato alcuna differenza quando mi sono sbarazzato di se

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

3) È più 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;
   ...
  }

di quello che

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

sembra...

4) Non si può scaricare la CPU, cioè le pile di scalper ecc. possono essere dimenticate.

 
Rorschach:

Alcune conclusioni.

1) Il pre-calcolo di h non ha avuto alcun effetto.

2) Nessuna differenza nel liberarsi se

3) È più lento,

di quello che

sembra...

4) Non si può scaricare la CPU, cioè le pile di scalper ecc. possono essere dimenticate.

In MT5, le pile di scalper possono facilmente funzionare in un thread senza OCL e non sovraccaricare la CPU. Naturalmente, questo non significa che non sia necessario. Solo un avviso.

Se usate la classe CCanvas quando costruite un montante, allora il carico di lavoro sarà proporzionale all'area del montante. Cioè, più grande è la finestra nel mull, più pesante è il carico, perché l'intera tela viene ridisegnata, non le singole parti modificate. Tuttavia, trasformando le celle dei becher in elementi indipendenti, esse possono essere aggiornate indipendentemente dal resto dell'area del kanvas, riducendo di diverse volte il tempo di ridisegno e il carico sul processore che ne deriva.

 
Реter Konow:

Su MT5, le pile di scalper possono facilmente lavorare in un thread, senza OCL e senza sovraccaricare il processore. Naturalmente, questo non significa che non sia necessario. Solo un avviso.

Se usate la classe CCanvas quando costruite un montante, allora il carico di lavoro sarà proporzionale all'area del montante. Cioè, più grande è la finestra nel mull, più pesante è il carico, perché l'intera tela viene ridisegnata, non le singole parti modificate. Tuttavia, trasformando le celle dei becher in elementi indipendenti, esse possono essere aggiornate indipendentemente dal resto dell'area del kanvas, riducendo di diverse volte il tempo di ridisegno e il carico sul processore che ne deriva.

4° punto in questione. Nell'esempio di Remnant3D, la CPU non viene quasi per niente caricata.

 
Rorschach:

Il punto 4 è in discussione. L'esempio di Remnant3D non carica quasi mai la CPU.

Questo è stato testato. La CPU su MT5, in caso di normale dinamica del canvas, non viene quasi caricata, se si ridisegnano le singole celle in cui il valore è cambiato.

Al contrario, se ogni valore in arrivo viene ridisegnato su tutta l'area del canvas, il processore sarà molto stressato.

La differenza è nel numero di valori reinizializzati nell'array di pixel. Dovete aggiornare selettivamente le singole aree e non avrete problemi di carico.

 
Реter Konow:

Questo è stato testato. La CPU su MT5, in caso di normale dinamica del canvas, non viene quasi caricata, se si ridisegnano le singole celle in cui il valore è cambiato.

Al contrario, se ogni valore in arrivo viene ridisegnato su tutta l'area del canvas, il processore sarà molto stressato.

La differenza è nel numero di valori reinizializzati nell'array di pixel. Dovete aggiornare selettivamente le singole aree e non avrete problemi di carico.

Questa è la cosa di Remnant3D: è una tela a tutto schermo e non carica la CPU.