DirectX - página 3

 
Rorschach:

Muito obrigado!

Seus cálculos estão em dobro? Então o resultado é particularmente impressionante.

Bem visto. De fato, em um só lugar ele flutuava em vez de dobrar:

D = fast_length(p);

Para que seja o dobro, precisamos corrigi-lo para

D = length(p);

Além disso, você pode se livrar da última linha (análoga à macro XRGB) aplicando uchar4 em vez de uint para o argumento *buf. Tente desta forma:

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

É realmente impressionante! O Fps é 1,5 vezes maior do que nos shaders.

Obrigado, o código funciona, sem degradação de desempenho, apenas moveu o canal alfa para o final na última linha:

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

É realmente impressionante! O Fps é 1,5 vezes maior do que nos shaders.

Obrigado, o código funciona, o desempenho não é degradado, apenas na última linha o canal alfa foi movido para o final:

Nesta implementação, o desempenho depende muito do número de centros (N). O ideal seria nos livrarmos do loop no núcleo, mas neste caso teremos que fazer S1 e S2 inteiros. Teremos que ver quão grande é a disseminação de seus valores e talvez possamos multiplicá-los por algo sem muito pecado. E então é possível transferir o loop para a terceira dimensão, o que teoricamente dará ganho de desempenho a altos valores de N.

Eu recebo 80-90 fps em meu HD 7950 no monitor Fullhd em N=128.

 
Serhii Shevchuk:

Nesta implementação, o desempenho depende muito do número de centros (N). Seria bom se livrar do laço no núcleo, mas então S1 e S2 teriam que ser inteiros. Teremos que ver quão grande é a disseminação de seus valores e talvez possamos multiplicá-los por algo sem muito pecado. E então é possível transferir um loop para a terceira dimensão, que teoricamente dará ganho de desempenho a altos valores de N.

Recebo 80-90 fps em meu HD 7950 em um monitor HD completo em N=128.

Meu 750ti tem 11 fps. Encontrei as especificações para os cartões:

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

Logicamente, a mudança para flutuar pode elevar o fps por um fator de 4 na amd e 32 na nvidia.

 

Fez uma cópia da versão do OCL. Estou chocado com o resultado. Em 1600 centros não foi possível carregar o vidia mais de 85%.

A otimização com h pré-calculado não tem nenhum efeito, mas é deixada com ela. Todos os cálculos estão em flutuação, não vejo a vantagem de usar o dobro, já que todas as funções retornam a flutuação de qualquer forma.

Arquivos anexados:
pixel.zip  1 kb
 

Algumas conclusões.

1) O pré-cálculo do h não teve efeito.

2) Eu não notei nenhuma diferença ao me livrar de se.

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

3) É mais 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;
   ...
  }

do que ela

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) Não se pode descarregar CPU, ou seja, pilhas de escalper, etc., podem ser esquecidas.

 
Rorschach:

Algumas conclusões.

1) O pré-cálculo do h não teve efeito.

2) Não há diferença em se livrar de

3) É mais lento,

do que ela

parece que...

4) Não se pode descarregar CPU, ou seja, pilhas de escalper, etc., podem ser esquecidas.

No MT5, as pilhas de escalper podem facilmente funcionar em uma única linha sem OCL e não sobrecarregar a CPU. Naturalmente, isto não significa que não seja necessário. Apenas uma FYI.

Se você usar a classe CCanvas ao construir um lingote, então a carga de trabalho será proporcional ao tamanho do lingote. Ou seja, quanto maior a janela na mull, mais pesada a carga, porque a tela inteira está sendo redesenhada, e não o indivíduo, peças trocadas. Entretanto, transformando as células do copo em elementos independentes, elas podem ser atualizadas independentemente do resto da área do kanvas, reduzindo o tempo de redesenho e a carga sobre o processador causada por ele por várias vezes.

 
Реter Konow:

No MT5, as pilhas de escalper podem trabalhar facilmente em uma única linha, sem OCL e sem sobrecarregar o processador. É claro, isso não significa que não seja necessário. Apenas uma FYI.

Se você usar a classe CCanvas ao construir um lingote, então a carga de trabalho será proporcional ao tamanho do lingote. Ou seja, quanto maior a janela na mull, mais pesada a carga, porque a tela inteira está sendo redesenhada, e não o indivíduo, peças trocadas. Entretanto, transformando as células do copo em elementos independentes, elas podem ser atualizadas independentemente do resto da área do kanvas, reduzindo o tempo de redesenho e a carga sobre o processador causada por ele por várias vezes.

4º ponto em questão. No exemplo do Remnant3D, a CPU mal é carregada.

 
Rorschach:

O ponto 4 está em questão. O exemplo do Remnant3D dificilmente carrega a CPU.

Isto já foi testado. A CPU no MT5, no caso da dinâmica normal da tela, quase não é carregada, se você redesenhar células individuais nas quais o valor mudou.

Pelo contrário, se cada valor recebido for redesenhado sobre toda a área de lona, o processador ficará muito estressado.

A diferença está no número de valores reinicializados na matriz de píxeis. Você precisa atualizar seletivamente áreas individuais e não terá problemas de carga.

 
Реter Konow:

Isto já foi testado. A CPU no MT5, no caso da dinâmica normal da tela, quase não é carregada, se você redesenhar células individuais nas quais o valor mudou.

Pelo contrário, se cada valor recebido for redesenhado sobre toda a área de lona, o processador ficará muito estressado.

A diferença está no número de valores reinicializados na matriz de píxeis. Você precisa atualizar seletivamente áreas individuais e não terá problemas de carga.

Esse é o problema do Remnant3D: é uma tela de tela cheia e não carrega a CPU.

Razão: