- ru.wikipedia.org
En un coup d'œil, pourquoi DirectCompute est nécessaire :
1) C'est pratique et efficace. Vous pouvez calculer et sortir immédiatement le résultat sur kanvas. Vous devez envoyer le calcul au Gpu via OpenCL, puis une autre requête pour la sortie vers Kanvas, et l'envoi via pcie est long.
2) Les api diffèrent beaucoup en termes de performances selon la tâche et le fournisseur de gpu. Et il y aura beaucoup à choisir.
3) Il y aura un choix de langue. Si quelqu'un connaît hlsl, il n'aura pas besoin d'apprendre opencl.
4) Le calcul et la sortie du résultat peuvent être écrits dans une seule langue, ce qui est pratique.
5) Pour le tas. Les sommets sont là, les pixels sont là, même les géométriques sont là, mais les calculs ne le sont pas.
6) Presque tout est prêt pour cela. DX est boulonné, il suffit d'ajouter un shader, il ne s'agit pas d'ajouter Kuda à partir de zéro.
7) Je veux faire une telle chose pour la formation.
8) Et le plus important.
- habr.com
- Roman Shatalov - roman@shatalov.su
- oldshatalov.ghost17.ru
Il y a OpenCL. J'ai le sentiment que ce sera beaucoup plus facile).
Il y a un soupçon que vous vous trompez un peu sur le forum.
Il y a un doute sur le fait que vous vous soyez trompé de sujet.
Code minimal, plus une tentative de comparaison des performances avec un kanvas normal (crooked way, got pcie bus score)
#include <Canvas\Canvas.mqh> #resource "/Files/vertex.hlsl" as string VS; #resource "/Files/pixel.hlsl" as string PS; struct VSInputVertex { float position[4]; static const DXVertexLayout s_layout[1]; }; const DXVertexLayout VSInputVertex::s_layout[1]= { {"POSITION", 0, DX_FORMAT_R32G32B32A32_FLOAT } }; void OnStart() { int size=500; CCanvas cc; cc.CreateBitmapLabel("11",100,100,size,size); cc.Erase(ColorToARGB(clrGreen)); cc.Update(); Sleep(1000); VSInputVertex vertex[]; ArrayResize(vertex,size*size); for(int y=0;y<size;y++) {for(int x=0;x<size;x++) {vertex[y*size+x].position[0]=2.f*(x+1)/size-1.f; vertex[y*size+x].position[1]=2.f*(y+1)/size-1.f; vertex[y*size+x].position[2]=0.5; vertex[y*size+x].position[3]=1.0; } } int hc=DXContextCreate(size,size); int hbv=DXBufferCreate(hc,DX_BUFFER_VERTEX,vertex); string s=""; int hsv=DXShaderCreate(hc,DX_SHADER_VERTEX,VS,"main",s); int hsp=DXShaderCreate(hc,DX_SHADER_PIXEL ,PS,"main",s); DXShaderSetLayout(hsv,VSInputVertex::s_layout); DXPrimiveTopologySet(hc,DX_PRIMITIVE_TOPOLOGY_POINTLIST); DXBufferSet(hc,hbv); DXShaderSet(hc,hsv); DXShaderSet(hc,hsp); DXContextClearDepth(hc); DXDraw(hc); uint image[]; ulong t1=GetMicrosecondCount(); DXContextGetColors(hc,image); ulong t2=GetMicrosecondCount(); for(int y=0;y<size;y++) for(int x=0;x<size;x++) cc.PixelSet(x,y,image[y*size+x]); ulong t3=GetMicrosecondCount(); cc.Update(); Print(t2-t1," ",t3-t2); Sleep(1000); DXRelease(hsp); DXRelease(hsv); DXRelease(hbv); DXRelease(hc); cc.Destroy(); }
https://www.mql5.com/ru/forum/227736
Transféré au shader. Les 15 premières secondes exécutent le code source sur le cpu, puis la version gpu.
"Vous devez déplacer le tableau m_pixels[] dans le fichier Canvas.mqh de protected : à public :"
#include <Canvas\Canvas.mqh> #resource "/Files/vertex.hlsl" as string VS; #resource "/Files/pixel.hlsl" as string PS; struct VSInputVertex {float position[4]; static const DXVertexLayout s_layout[1]; }; const DXVertexLayout VSInputVertex::s_layout[1]={{"POSITION", 0, DX_FORMAT_R32G32B32A32_FLOAT}}; struct PSInputBuffer {float resolution[2]; float time; float dummy; }; void OnStart() {CCanvas C; int Width=(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); // получаем Ширину окна int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту окна if(!C.CreateBitmapLabel(0,0,"CanvasExamlple",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // создаем канвас размером текущего окна Print("Error creating canvas: ",GetLastError()); //---CPU--- uint i=0,j=100000; int size=Width*Height; uchar h[25600]; for (int w=0;w<25600;w++) h[w]= uchar(128+128*sin(double(w)/256));//создаем массив для ускорения работы double X1=0,Y1=0,X2=0,Y2=0; uint t0=GetTickCount(); uint t1=0; while(!IsStopped()) {int pos=int(i%size); if(pos==0) {C.TextOut(100,100,"CPU FPS: "+DoubleToString(1000./(GetTickCount()-t1),2),clrWhite); t1=GetTickCount(); C.Update(); if(t1-t0>15000) break; //Sleep(30); X1= Width-(sin((double)j/100)*(double)Width); Y1= Height-(cos((double)j/140)*(double)Height); X2= Width+(cos((double)j/80)*(double)Width); Y2= Height+(sin((double)j/20)*(double)Height); j++; } int X=pos%Width; int Y=int(pos/Width); double d= ((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))/(((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y))+((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y))); C.m_pixels[pos]=XRGB(h[int(d*11520)],h[int(d*17920)],h[int(d*6400)]); i++; } //---GPU--- VSInputVertex vertex[]= {{{-1,-1,0.5,1.0}},{{-1,1,0.5,1.0}},{{1,1,0.5,1.0}},{{1,-1,0.5,1.0}}}; int hc=DXContextCreate(Width,Height); int hbv=DXBufferCreate(hc,DX_BUFFER_VERTEX,vertex); uint index[]={0,1,2, 2,3,0}; int hbi=DXBufferCreate(hc,DX_BUFFER_INDEX ,index ); string s=""; int hsv=DXShaderCreate(hc,DX_SHADER_VERTEX,VS,"main",s); int hsp=DXShaderCreate(hc,DX_SHADER_PIXEL ,PS,"main",s); int hi[1]; hi[0]=DXInputCreate(hc,sizeof(PSInputBuffer)); DXShaderInputsSet(hsp,hi); DXShaderSetLayout(hsv,VSInputVertex::s_layout); DXPrimiveTopologySet(hc,DX_PRIMITIVE_TOPOLOGY_TRIANGLELIST); DXBufferSet(hc,hbv); DXBufferSet(hc,hbi); DXShaderSet(hc,hsv); DXShaderSet(hc,hsp); PSInputBuffer frame_data; frame_data.resolution[0]=(float)Width; frame_data.resolution[1]=(float)Height; for(uint n=100000;!IsStopped();n++) {DXContextClearDepth(hc); frame_data.time=(float)n; DXInputSet(hi[0],frame_data); DXDrawIndexed(hc); DXContextGetColors(hc,C.m_pixels); C.TextOut(100,100,"GPU FPS: "+DoubleToString(1000./(GetTickCount()-t1),2),clrWhite); C.Update(); t1=GetTickCount(); } DXRelease(hi[0]); DXRelease(hsp); DXRelease(hsv); DXRelease(hbv); DXRelease(hbi); DXRelease(hc); C.Destroy(); }
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation