CUDA рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╡рд┐рджреНрдпреБрдд рдХреНрд╖реЗрддреНрд░ рдХреА рдореЙрдбрд▓рд┐рдВрдЧ рдХрд░рдирд╛

рдпрд╣ рд▓реЗрдЦ рдпрд╣ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ CUDA рддрдХрдиреАрдХ рдЖрд╡реЗрд╢рд┐рдд рдХрдгреЛрдВ рдХреА рд╕рд░рд▓ рдЕрдВрддрдГрдХреНрд░рд┐рдпрд╛ рдХреЛ рдЕрдиреБрдХрд░рдг рдХрд░ рд╕рдХрддреА рд╣реИ (рджреЗрдЦреЗрдВ CoulombтАЩs Law ) рдПрдХ рд╕реНрдерд┐рд░ рдЪрд┐рддреНрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдлреНрд░реАрдЧреНрд▓реВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред
рдЬреИрд╕рд╛ рдХрд┐ рд╡реЗ рдЕрдХреНрд╕рд░ рд╣реИрдмреЗ рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

рдЯрд░реНрдмреЛ рдкрд╛рд╕реНрдХрд▓ рдФрд░ рдмреЛрд░рд▓реИрдВрдб рд╕реА 5.02 рдХреЗ рджрд┐рдиреЛрдВ рдореЗрдВ, рдореБрдЭреЗ рдкреНрд░рдХреГрддрд┐ рдХреА рд╕рд░рд▓ рднреМрддрд┐рдХ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдЕрдиреБрдХрд░рдг рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рдереА - рдЪрд╛рд╣реЗ рд╡рд╣ рдЧреБрд░реБрддреНрд╡рд╛рдХрд░реНрд╖рдг рдЖрдХрд░реНрд╖рдг рдмрд▓ рд╣реЛ рдпрд╛ рдХреВрд▓рдореНрдм рдЗрдВрдЯрд░реИрдХреНрд╢рдиред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдХрдИ рд╕реМ рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рд╡рд╛рд▓реЗ рдПрдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреА рд╢рдХреНрддрд┐ рд╕рд░рд▓ рдЧрдгрд┐рддреАрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдереА, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдХрдИ рдереЗред

рдпрджреНрдпрдкрд┐ рдореИрдВ рдПрдХ рдкреЛрдЧреНрд░реЛрдорд┐рд╕реНрдЯ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рдмрд╛рд░ рдПрдХ рджреВрд░ рдХреЗ рдмрдЪрдкрди рдХреЛ рдпрд╛рдж рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдФрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рд╕реАрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдФрд░ рдХрд┐рд╕реА рддрд░рд╣ рдореИрдВрдиреЗ рдХрд┐рд╕реА рднреА рдЙрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рд╛рдордЧреНрд░реА рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдЧреБрд░реБрддреНрд╡рд╛рдХрд░реНрд╖рдг рдмрд╛рддрдЪреАрдд рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд┐рдпрд╛ред рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдиреНрдпреВрдЯрди рдХреЗ рдирд┐рдпрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдиреАрдЪреЗ рдХрд╛ рдХрдг "рд╕реВрд░реНрдп" рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдШреВрдорддрд╛ рд╣реИ:

рдпрджрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛, рдФрд░ рдЙрддреНрд╕рд╛рд╣ рдореБрдЭреЗ рдирд╣реАрдВ рдЫреЛрдбрд╝реЗрдЧрд╛, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдбреЗрдореЛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рджреБрд╖реНрдЯ рдкрдХреНрд╖рд┐рдпреЛрдВ рдХреЛ рд╢реВрдиреНрдп рдореЗрдВ рд▓рд┐рдЦ рд╕рдХреЗрдВред

рддреЛ, рдЙрджрд╛рд╕реАрди рдмрдВрдж рдХрд░реЛ, рдЪрд▓реЛ pogrom рдХрд╛рд░реНрдпрдХреНрд░рдоред рдореЗрд░рд╛ рдордВрдЪ рдЙрдмрдВрдЯреВ рд╡рд╛рд▓рд╛ рдПрдХ рд▓реИрдкрдЯреЙрдк рд╣реИ рдФрд░ рдПрдХ GeForce GT 540m рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХрд╛рд░реНрдб рдФрд░ CUDA рдЯреВрд▓рдХрд┐рдЯ 5.0 рд╕реНрдерд╛рдкрд┐рдд рд╣реИред рдпрджрд┐ рдЖрдк CUDA рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкреБрд╕реНрддрдХ, CUDA by Example рдкрд░ рд╕рд▓рд╛рд╣ рджреЗ рд╕рдХрддрд╛ рд╣реВрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, Nsight рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╕реЗ рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ GLU, GL, рдЧреНрд▓реВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлреНрд░реАрдЧреНрд▓реВрдЯ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред рдпрд╣ рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдореА рд╡реЗрдХреНрдЯрд░ рдлрд╝реАрд▓реНрдб рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдЬрд┐рд╕рдХреА рд╣рдо рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред main рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реА рдлрд╝рд╛рдЗрд▓ рдХреА рдЕрдиреБрдорд╛рдирд┐рдд рд╕рдВрд░рдЪрдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧреА:
 #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { // Initialize freeglut // ... // Initialize Host and Device variables // ... // Launch Kernel to render the image // Display Image // Free resources return 0; } 

рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рджрд┐рдЦрддрд╛ рд╣реИред рдкрд╣рд▓реЗ, рдЖрдЗрдП рд╣рдо рдЙрд╕ рдЖрдХрд╛рд░ рдХреА рдПрдХ рд╡рд┐рдВрдбреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ, рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЬрд╝рд░реВрд░рдд рд╣реИ, рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдФрд░ рдПрдХ рдмреНрд▓реИрдХ рд╕реНрдХреНрд░реАрди рд░реЗрдВрдбрд░ рдХрд░реЗрдВред рд╡реИрд╕реЗ, рдореИрдВ рдЖрдкрдХреЛ рд╕реНрдкрд╖реНрдЯ рдмрд╛рдд рдмрддрд╛рдКрдВрдЧрд╛: рдпрджрд┐ рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдкрд░рд┐рдЪрд┐рдд рд╣реИ, рддреЛ рдмрд╕ рдЗрд╕реЗ Google рдХрд░реЗрдВ ред

рд╡рд┐рдВрдбреЛ рдЖрд░рдВрднреАрдХрд░рдг


рдЬрдм рд╕реЗ рдореИрдВрдиреЗ рдЖрд╡реЗрджрди рдХреА рдХрд▓реНрдкрдирд╛ рдХреА, рдореИрдВрдиреЗ рдЦрд┐рдбрд╝рдХреА рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЖрдХрд╛рд░ рджреЗрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдмрдирд╛рдИ рдереА, рдореИрдВрдиреЗ рд╡реИрд╢реНрд╡рд┐рдХ рд╡реИрдЬреНрдЮрд╛рдирд┐рдХреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЗрд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛:
 const int width = 1280; const int height = 720; 

рдЕрд░реЗ рд╣рд╛рдБ! C ++ рдФрд░ C99 рд╢реИрд▓рд┐рдпреЛрдВ рдХреЗ рдорд┐рд╢реНрд░рдг рдХреЗ рд▓рд┐рдП рдХрдбрд╝рд╛рдИ рд╕реЗ рдиреНрдпрд╛рдп рди рдХрд░реЗрдВред рдореБрдЭреЗ рдХрднреА-рдХрднреА рдХреБрдЫ рдЪреАрдЬреЗрдВ рдорд┐рд▓ рдЬрд╛рддреА рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ, рдЙрдкрдпреЛрдЧреА, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рд╕реАрдпреВрдбреАрдП рдХреЗ рд╕рд╛рде рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рд╢реИрд▓реА рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрд▓реЙрдХ рдХреЛ рдирд╣реАрдВ рдЫреЛрдбрд╝рд╛ рд╣реИред

рд╡рд┐рдВрдбреЛ рд╣реА, рдПрд╕реНрдХреЗрдк рдХреБрдВрдЬреА рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рдирд╛ рдФрд░ рд╕рд░рд▓ рдХреЛрдб рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
 #include <GL/freeglut.h> #include <GL/gl.h> #include <GL/glext.h> // ... void key(unsigned char key, int x, int y) { switch (key) { case 27: printf("Exit application\n"); glutLeaveMainLoop(); break; } } void draw(void) { glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); // glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, screen); glFlush(); } // ... // Initialize freeglut glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowSize(width, height); glutCreateWindow("Electric field"); glutDisplayFunc(draw); glutKeyboardFunc(key); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); // ... // Display Image glutMainLoop(); 

рдЬрдм рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдПрдХ рдХрд╛рд▓реА рд╕реНрдХреНрд░реАрди рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдЧрд╛ред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдпрд╣рд╛рдВ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдХреЛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрд╛рддреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ:

рдмреНрд▓реЙрдХ рдФрд░ рдереНрд░реЗрдб рдореЗрдВ рд╡рд┐рднрд╛рдЬрди рдХреА рдЧрдгрдирд╛


рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд▓рд┐рдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдЕрдкрдиреЗ рд▓рд┐рдП рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ рдХрд┐ рдмреНрд▓реЙрдХ рдФрд░ рд╕реНрдЯреНрд░реАрдо рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреНрдпрд╛ рд╣реИ, рдФрд░ рдЙрдирдХреЗ рдЖрдпрд╛рдо рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрджрд┐ рд╣рдо рддрдХрдиреАрдХреА рд╡рд┐рд╡рд░рдг рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдмреНрд▓реЙрдХ рдПрдХ рд╕реЗрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреНрд░рд╡рд╛рд╣ рд╣реЛрддреЗ рд╣реИрдВред рдЬрдм рдмреНрд▓реЙрдХреЛрдВ рдХреА рдПрдХ рдкреВрд░реА рдЧреНрд░рд┐рдб рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рдХрд┐рд╕реА рд╕рдордп рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдмреНрд▓реЙрдХ рдЕрдкрдиреЗ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рд╢реВрдЯ рдХрд░рддрд╛ рд╣реИ, рдЙрдирдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рдХреЛ рджреВрд╕рд░реЗ рдмреНрд▓реЙрдХ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рддреЛ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдмреНрд▓реЙрдХ рдХреЛ рдПрдХ рдЖрдпрд╛рдореА рдкрдЯреНрдЯреА рдореЗрдВ рдпрд╛ рджреЛ рдЖрдпрд╛рдореА рдЧреНрд░рд┐рдб рдореЗрдВ рдЧрд░реНрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдзрд╛рд░рд╛рдПрдВ, рдмрджрд▓реЗ рдореЗрдВ, рдПрдХ рдЖрдпрд╛рдореА рдкрдЯреНрдЯреА рдпрд╛ рджреЛ-рдЖрдпрд╛рдореА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдмреНрд▓реЙрдХ рдореЗрдВ рднреА рд╕реНрдерд┐рдд рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рд╡реИрд╕реЗ, рддреАрди рдЖрдпрд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд▓реНрдк рд╕рдВрднрд╡ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЙрдиреНрд╣реЗрдВ рдпрд╛рдж рдХрд░реВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЕрднреА рддрдХ рдореЗрд░реЗ рдХрд╛рд░реНрдп рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реИрдВред

рдореИрдВ рд╕реНрдХреНрд░реАрди рдХреЛ рдмрдбрд╝реЗ рд╡рд░реНрдЧреЛрдВ (рдмреНрд▓реЙрдХ) рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рдЬрд┐рд╕рдХреЗ рдЕрдВрджрд░ рдкрд┐рдХреНрд╕рд▓ рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдРрд╕рд╛ рдХрд╛рд░реНрдп рдПрдХ рдЧреНрд░рд╛рдлрд┐рдХ рдХрд╛рд░реНрдб рдХрд╛ рдЗрд╖реНрдЯрддрдо рдЙрдкрдпреЛрдЧ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдХреНрд░реАрди рдХреЛ рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рд░рд▓ рдЕрдВрдХрдЧрдгрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ - рдореБрдЭреЗ рдмреНрд▓реЙрдХ рдХреЗ рднреАрддрд░ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдиреБрдордд рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдкрддрд╛ рдЪрд▓реЗрдЧрд╛, рдФрд░ рдлрд┐рд░ рдХреНрд╖реИрддрд┐рдЬ рдФрд░ рд▓рдВрдмрд╡рдд рд░реВрдк рд╕реЗ рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рд╡рд┐рдВрдбреЛ рдХрд╛ рдЖрдХрд╛рд░ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВред

рдХрд┐рд╕реА рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо cudaGetDeviceProperties рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:
 int threadsCount(void) { int deviceCount = 0; cudaGetDeviceCount(&deviceCount); if (deviceCount <= 0) { printf("No CUDA devices\n"); exit(-1); } cudaDeviceProp properties; cudaGetDeviceProperties(&properties, 0); return properties.maxThreadsPerBlock; } 

рдореЗрд░рд╛ рдХрд╛рд░реНрдб 1024 рдирдВрдмрд░ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореИрдВ рд╕рднреА рдзрд╛рд░рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдХреНрдпреЛрдВрдХрд┐ рдбрд┐рдмрдЧ рдореЛрдб рдореЗрдВ, рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ float рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╕рдордп, рдореБрдЭреЗ рддреНрд░реБрдЯрд┐ cudaErrorLaunchOutOfResources рдкреНрд░рд╛рдкреНрдд cudaErrorLaunchOutOfResources ред рдореБрдЭреЗ рдЕрднреА рднреА рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓ рдкрд╛рдпрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдкрд░реНрдпрд╛рдкреНрдд рд╕рдВрд╕рд╛рдзрди рдХреНрдпреЛрдВ рдирд╣реАрдВ рдереЗ (рдпрд╛ рд░рдЬрд┐рд╕реНрдЯрд░, рдЬреИрд╕рд╛ рдХрд┐ рдЗрдВрдЯрд░рдиреЗрдЯ рд▓рд┐рдЦрддрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП рдХреЗрд╡рд▓ рддреАрди рд╕рдорд╛рдзрд╛рди рдЬреЛ рдореБрдЭреЗ рдорд┐рд▓ рд╕рдХрддреЗ рдереЗ рд╡реЗ рдереЗ рдкреНрд░рддрд┐ рдмреНрд▓реЙрдХ рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдирд╛, рд╕рдВрдХрд▓рди рдХрд░рддреЗ рд╕рдордп рд░рд┐рд▓реАрдЬрд╝ рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде maxrregcount рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реВрдиреНрдп рд╕реЗ рдЕрдзрд┐рдХред
рдпрджрд┐ рдЖрдк рдореЗрд░реЗ рд▓реЗрдЦ рдХреЛ рдЗрд╕ рдмрд┐рдВрджреБ рддрдХ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдЦреБрд╢реА рд╣реИ рдХрд┐ рдпрд╣ рд╡реНрдпрд░реНрде рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рд░рд╛рдд рдХреЛ рдХрдВрдкреНрдпреВрдЯрд░ рдХреЗ рд╕рд╛рдордиреЗ рдмреИрдареВрдВред рдФрд░ рдпрджрд┐ рдЖрдк рдЙрддреНрддрд░ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдХреИрд╕реЗ рдкрддрд╛ рдХрд░реЗрдВ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрд░реА рдЧрд▓рддреА рдХреНрдпрд╛ рдереА, рдФрд░ рдореБрдЭреЗ рдпрд╣ рдмрддрд╛рдПрдВ, рддреЛ рдореБрдЭреЗ рджреЛрдЧреБрдирд╛ рдЦреБрд╢реА рд╣реЛрдЧреАред

рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдмреНрд▓реЙрдХ рдФрд░ рдкреНрд░рд╡рд╛рд╣ рдореЗрдВ рддреЛрдбрд╝ рджреЗрдВрдЧреЗ:
 void setupGrid(dim3* blocks, dim3* threads, int maxThreads) { threads->x = 32; threads->y = maxThreads / threads->x - 2; // to avoid cudaErrorLaunchOutOfResources error blocks->x = (width + threads->x - 1) / threads->x; blocks->y = (height + threads->y - 1) / threads->y; } // ... // Initialize Host dim3 blocks, threads; setupGrid(&blocks, &threads, threadsCount()); printf("Debug: blocks(%d, %d), threads(%d, %d)\nCalculated Resolution: %dx %d\n", blocks.x, blocks.y, threads.x, threads.y, blocks.x * threads.x, blocks.y * threads.y); 

рдкрд░рд┐рдгрд╛рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧрд╛ (рдореИрдВрдиреЗ рдЬрд╛рдирдмреВрдЭрдХрд░ рдЙрди рдмреНрд▓реЙрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдПрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХреА рд╣реИ рдЬрд╣рд╛рдВ рд╕реНрдХреНрд░реАрди рдХрд╛ рдЖрдХрд╛рд░ рдереНрд░реЗрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ):
 Debug: blocks(40, 24), threads(32, 30) Calculated Resolution: 1280 x 720 

рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рдЕрднреНрдпрд╛рд╕


рд╢реБрд▓реНрдХ, рджреВрд░реА, рдкреЗрдВрдбреЗрдВрдЯ рдФрд░ рдЕрдиреБрдкрд╛рдд - рдЬреЛ рдЕрдЪреНрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рдореЙрдбрд▓рд┐рдВрдЧ рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ рд╣рдо рдЕрдм рд╕реБрдкрд░-рдЫреЛрдЯреЗ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЧрдгрдирд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЧрд╛рдпрдм рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХрд╛рд░реНрдп рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддреЗ рд╣реИрдВ:

рдПрдХ рд╢реБрд▓реНрдХ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдВрд░рдЪрдирд╛ рд╣реИ (рдЬреИрд╕реЗ рд╕реНрдХреНрд░реАрди рдкрд░)ред
 struct charge { int x, y, q; }; 

рдПрдХ рдмрд┐рдВрджреБ рдкрд░ рд╡рд┐рджреНрдпреБрдд рдХреНрд╖реЗрддреНрд░ рдХреА рддрд╛рдХрдд рдПрдХ рд╡реЗрдХреНрдЯрд░ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдЕрдиреБрдорд╛рдиреЛрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╡реНрдпрдХреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЙрдиреНрд╣реЗрдВ рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ (рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдореБрдЭреЗ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдорд┐рд▓реА:
 const float k = 50.0f; const float minDistance = 0.9f; // not to divide by zero const float maxForce = 1e7f; struct force { float fx, fy; __device__ force() : fx(0.0f), fy(0.0f) { } __device__ force(int fx, int fy) : fx(fx), fy(fy) { } __device__ float length2() const { return (fx * fx + fy * fy); } __device__ float length() const { return sqrtf(length2()); } __device__ void calculate(const charge& q, int probe_x, int probe_y) { // F(1->2) = k * q1 * q2 / r(1->2)^2 * vec_r(1->2) / abs(vec_r(1->2)) // e = vec_F / q2 fx = probe_x - qx; fy = probe_y - qy; float l = length(); if (l <= minDistance) { return; } float e = k * qq / (l * l * l); if (e > maxForce) { fx = fy = maxForce; } else { fx *= e; fy *= e; } } __device__ force operator +(const force& f) const { return force(fx + f.fx, fy + f.fy); } __device__ force operator -(const force& f) const { return force(fx - f.fx, fy - f.fy); } __device__ force& operator +=(const force& f) { fx += f.fx; fy += f.fy; return *this; } __device__ force& operator -=(const force& f) { fx -= f.fx; fy -= f.fy; return *this; } }; 

рдореЗрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╕рд░рд▓ рд╣реИ - рдореИрдВ рддрдирд╛рд╡ рд╡рд╛рд▓реЗ рд╡реИрдХреНрдЯрд░реЛрдВ рдХрд╛ рдПрдХ рджреЛ-рдЖрдпрд╛рдореА рд╕рд░рдгреА рдмрдирд╛рдКрдВрдЧрд╛ред рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдкрд░, рддрдирд╛рд╡ рдХреВрд▓рдореНрдм рдмрд▓реЛрдВ рдХреЗ рд╡реИрдХреНрдЯрд░ рдХреЗ рдпреЛрдЧ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧрд╛ред рдпрд╣ рдмрд╣реБрдд рдмреБрд░рд╛ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЕрдиреНрдпрдерд╛ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛ред рдпрд╣ рдХрд╣рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдХреЛрдб рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛ (рдЖрдк рдЗрд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрднреА рддрдХ рдирд╣реАрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ):
  force temp_f; for (int i = 0; i < chargeCount; i++) { temp_f.calculate(charges[i], x, y); *f += temp_f; } 

рдпрджрд┐ рд╣рдо рдЪрд╛рд░реНрдЬ рдореЗрдВ рдЖрддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рддрдирд╛рд╡ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реВрдВ (рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рд╢реВрдиреНрдп рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред рддреЛ рд╕реНрдХреНрд░реАрди рдкрд░ рдЖрдкрдХреЛ рдПрдХ рдмреНрд▓реИрдХ рдбреЙрдЯ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП - рдПрдХ рдЪрд╛рд░реНрдЬред

рдЕрдм рдЬрдм рд╣рдордиреЗ рдЗрдиреНрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдмрдирд╛рдпрд╛ рд╣реИ - CUDA рдХреЗ рд▓рд┐рдП рдХреЛрдбред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрд╡рд╢реНрдпрдХ рд╣реЛрд╕реНрдЯ рдФрд░ рдбрд┐рд╡рд╛рдЗрд╕ рдЪрд░ рдмрдирд╛рдПрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдореБрдХреНрдд рдХрд░реЗрдВ!

рд╣рдо рд╕рдВрд╕рд╛рдзрди рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдореБрдХреНрдд рдХрд░рддреЗ рд╣реИрдВ


рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:


рд╣рдо рдмрдирд╛рддреЗ рд╣реИрдВ:
 uchar4* screen = NULL; // ... screen = (uchar4*) malloc(width * height * sizeof(uchar4)); memset(screen, 0, width * height * sizeof(uchar4)); uchar4 *dev_screen = NULL; cudaMalloc((void**) &dev_screen, width * height * sizeof(uchar4)); cudaMemset(dev_screen, 0, width * height * sizeof(uchar4)); // ... // Free resources free(screen); screen = NULL; cudaFree(dev_screen); dev_screen = NULL; 

рд╣рдо рдХреЗрд╡рд▓ рдЖрд░реЛрдкреЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рд╕рдорд╛рди рдЪрд┐рддреНрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдЬрдирд░реЗрдЯрд░ рдХреЛ рд░реАрд╕реЗрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВред рдпрджрд┐ рдЖрдк рд╣рд░ рдмрд╛рд░ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреНрд╖реЗрддреНрд░ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдПрдХ srand рдХреЙрд▓ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
 const int chargeCount = 10; __constant__ charge dev_charges[chargeCount]; const int maxCharge = 1000; const int minCharge = -1000; // ... void prepareCharges(void) { charge* charges = (charge*) malloc(chargeCount * sizeof(charge)); for (int i = 0; i < chargeCount; i++) { charges[i].x = rand() % width; charges[i].y = rand() % height; charges[i].q = rand() % (maxCharge - minCharge) + minCharge; printf("Debug: Charge #%d (%d, %d, %d)\n", i, charges[i].x, charges[i].y, charges[i].q); } cudaMemcpyToSymbol(dev_charges, charges, chargeCount * sizeof(charge)); } // ... prepareCharges(); 

рдпрд╛рдж рд░рдЦреЗрдВ рдХрдореЗрдВрдЯ рдЖрдЙрдЯ рд▓рд╛рдЗрди рд╕реНрдХреНрд░реАрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ? рдЕрдм рдЖрдк рдЗрд╕реЗ рдЕрдирд╕реБрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
  glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, screen); 

рдПрдХ рдХрд░реНрдиреЗрд▓ рдмрдирд╛рдПрдБ


рдЕрдм рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВ рдЬрд┐рд╕реЗ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдореЗрдВ рд╕реНрдХреНрд░реАрди рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣реЗрдВрдЧреЗред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░реЗрдЧрд╛: рдпрд╣ рдХреНрд╖реЗрддреНрд░ рдХреА рддрд╛рдХрдд рдХреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдЧрд╛, рдФрд░ рдПрдХ рдмрд┐рдВрджреБ рдкрд░ рдХреБрдЫ рд░рдВрдЧ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ред

 __device__ uchar4 getColor(const force& f) { uchar4 color; color.x = color.y = color.z = color.w = 0; float l = f.length(); color.x = (l > maxLengthForColor ? 255 : l * 256 / maxLengthForColor); return color; } __global__ void renderFrame(uchar4* screen) { // build the field and render the frame } 

рдХреЛрд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ... рдФрд░ рдЕрднреА рддрдХ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ:
  // Launch Kernel to render the image renderFrame<<<blocks, threads>>>(dev_screen); cudaMemcpy(screen, dev_screen, width * height * sizeof(uchar4), cudaMemcpyDeviceToHost); 

рдЕрдм renderFrame рдХреБрдЫ рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд╣рдореЗрдВ рдЬреЛ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:
 __global__ void renderFrame(uchar4* screen) { int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; force f, temp_f; for (int i = 0; i < chargeCount; i++) { temp_f.calculate(dev_charges[i], x, y); f += temp_f; } screen[x + y * width] = getColor(f); } 

рдирд┐рд╖реНрдХрд░реНрд╖


рдЕрдХреНрд╕рд░ рд▓реЛрдЧ рдПрдХ рд▓реЗрдЦ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдирд┐рд╖реНрдХрд░реНрд╖ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣рд╛рдВ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рдореИрдВрдиреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛ред рдЖрдк рдпрд╣рд╛рдВ рд▓рдЧрднрдЧ рдЦрд╛рд▓реА рднрдВрдбрд╛рд░ рдХрд╛ рд▓рд┐рдВрдХ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЬрдЧрд╣ рд╣реИ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рдПрдиреАрдореЗрд╢рди рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЬрдм рд╢реБрд▓реНрдХ рдЪрд▓рддреЗ рд╣реИрдВ рддреЛ рдХреНрд╖реЗрддреНрд░ рдХреИрд╕реЗ рдмрджрд▓рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдлрд┐рд░, рдЕрдЧрд░ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред

Source: https://habr.com/ru/post/In164499/


All Articles