Advertisement
Guest User

Nbody karasiki V2.5

a guest
Oct 9th, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.98 KB | None | 0 0
  1. #include "cuda_runtime.h"
  2. #include "device_launch_parameters.h"
  3. #include <omp.h>
  4. #include <GL/glut.h>
  5. #include <cmath>
  6. #include <iostream>
  7. #include <ctime>
  8. #include <cstring>
  9. #include <cstdio>
  10.  
  11. const int N = 8000;
  12. const int h = 1000;
  13. const int w = 1000;
  14.  
  15. //For CUDA
  16. const int blocksize = 500; //1024 max
  17. int nblocks = N / blocksize;
  18. int button = 1;
  19. float *CU_POSM, *CU_POSR, *CU_POSX, *CU_POSY, *CU_POSZ;
  20.  
  21. //For rotate
  22. float rot_x = 0, rot_y = 0, x_angle = 0, y_angle = 0;
  23.  
  24. //Point coord
  25. float POSX[N], POSY[N], POSZ[N], float POSR[N * 3];
  26. //Point mass
  27. float POSM[N];
  28.  
  29. void initialization()
  30. {
  31.     glClearColor(0, 0, 0, 1);
  32.     glMatrixMode(GL_MODELVIEW);
  33.     glLoadIdentity();
  34.     glOrtho(-1000, 1000, -1000, 1000, -1000, 1000);
  35. }
  36.  
  37. void display()
  38. {
  39.     //FPS meter
  40.     static float fps, time_f, timebase = 0;
  41.     static int frames = 0;
  42.     static char res[5 + 31] = "FPS: ";
  43.  
  44.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  45.     glEnable(GL_DEPTH_TEST);
  46.     glPushMatrix();
  47.     glRotatef(x_angle, 1.0, 0.0, 0.0); //Rot axis X
  48.     glRotatef(y_angle, 0.0, 1.0, 0.0); //Rot axis Y
  49.  
  50.     glBegin(GL_POINTS);
  51.     for (int draw = 0; draw < N; draw++) {
  52.         glColor3f(1, 1, 1);
  53.         glVertex3f(POSX[draw], POSY[draw], POSZ[draw]);
  54.     }
  55.     glEnd();
  56.  
  57.     glBegin(GL_LINES);
  58.     //Axis X
  59.     glColor3f(1, 0, 0);
  60.     glVertex3f(-500.0, -500.0, -500.0);
  61.     glVertex3f(-250.0, -500.0, -500.0);
  62.     //Axis Y
  63.     glColor3f(0, 1, 0);
  64.     glVertex3f(-500.0, -500.0, -500.0);
  65.     glVertex3f(-500.0, -250.0, -500.0);
  66.     //Axis Z
  67.     glColor3f(0, 0, 1);
  68.     glVertex3f(-500.0, -500.0, -500.0);
  69.     glVertex3f(-500.0, -500.0, -250.0);
  70.     glEnd();
  71.  
  72.     glPopMatrix();
  73.     glDisable(GL_DEPTH_TEST);
  74.     glutSwapBuffers();
  75.  
  76.     //FPS calc + name & display on window
  77.     frames++;
  78.     time_f = glutGet(GLUT_ELAPSED_TIME);
  79.     if (time_f - timebase >= 1000)
  80.     {
  81.         fps = frames*1000.0 / (time_f - timebase);
  82.         timebase = time_f;
  83.         frames = 0;
  84.         sprintf(res, "Nbody karasiki V2.5 | FPS: %.3f", fps);
  85.         glutSetWindowTitle(res);
  86.     }
  87. }
  88.  
  89. //CPU_OpenMP
  90. void OMP_Math()
  91. {
  92.     float AX_M, AY_M, AZ_M, det_X, det_Y, det_Z, den;
  93. #pragma omp parallel for private(den, AX_M, AY_M, AZ_M)
  94.     for (int first = 0; first < N; first++) {
  95.         AX_M = 0;
  96.         AY_M = 0;
  97.         AZ_M = 0;
  98.         for (int next = 0; next < N; next++) {
  99.             if ((first != next) && ((POSX[next] != POSX[first]) || (POSY[next] != POSY[first]) || (POSZ[next] != POSZ[first]))) {
  100.                 det_X = POSX[next] - POSX[first];
  101.                 det_Y = POSY[next] - POSY[first];
  102.                 det_Z = POSZ[next] - POSZ[first];
  103.                 den = (POSM[next] * POSM[first]) / (100000 * pow((det_X*det_X + det_Y*det_Y + det_Z*det_Z), 3 / 2));
  104.                 AX_M += det_X * den;
  105.                 AY_M += det_Y * den;
  106.                 AZ_M += det_Z * den;
  107.             }
  108.         }
  109.         POSR[first] += AX_M;
  110.         POSR[first + N] += AY_M;
  111.         POSR[first + N + N] += AZ_M;
  112.        
  113.         POSX[first] += POSR[first];
  114.         POSY[first] += POSR[first + N];
  115.         POSZ[first] += POSR[first + N + N];
  116.     }
  117. }
  118.  
  119. //CUDA_Device
  120. __global__ void addKernel(float *POSM, float *POSX, float *POSY, float *POSZ, float *POSR)
  121. {
  122.     float AX_M, AY_M, AZ_M, det_X, det_Y, det_Z, den;
  123.     int first = threadIdx.x + blockIdx.x * blockDim.x;
  124.     AX_M = 0;
  125.     AY_M = 0;
  126.     AZ_M = 0;
  127.     for (int next = 0; next < N; next++) {
  128.         if ((first != next) && ((POSX[next] != POSX[first]) || (POSY[next] != POSY[first]) || (POSZ[next] != POSZ[first]))) {
  129.             det_X = POSX[next] - POSX[first];
  130.             det_Y = POSY[next] - POSY[first];
  131.             det_Z = POSZ[next] - POSZ[first];
  132.             den = (POSM[next] * POSM[first]) / (100000 * pow((det_X*det_X + det_Y*det_Y + det_Z*det_Z), 3 / 2));
  133.             AX_M += det_X * den;
  134.             AY_M += det_Y * den;
  135.             AZ_M += det_Z * den;
  136.         }
  137.     }
  138.     POSR[first] += AX_M;
  139.     POSR[first + N] += AY_M;
  140.     POSR[first + N + N] += AZ_M;
  141.    
  142.     POSX[first] += POSR[first];
  143.     POSY[first] += POSR[first + N];
  144.     POSZ[first] += POSR[first + N + N];
  145. }
  146.  
  147. //CUDA_Host
  148. void GPU_Math()
  149. {
  150.     cudaMalloc((void**)&CU_POSM, N * sizeof(float));
  151.     cudaMalloc((void**)&CU_POSX, N * sizeof(float));
  152.     cudaMalloc((void**)&CU_POSY, N * sizeof(float));
  153.     cudaMalloc((void**)&CU_POSZ, N * sizeof(float));
  154.     cudaMalloc((void**)&CU_POSR, 3 * N * sizeof(float));
  155.  
  156.     cudaMemcpy(CU_POSM, POSM, N * sizeof(float), cudaMemcpyHostToDevice);
  157.     cudaMemcpy(CU_POSX, POSX, N * sizeof(float), cudaMemcpyHostToDevice);
  158.     cudaMemcpy(CU_POSY, POSY, N * sizeof(float), cudaMemcpyHostToDevice);
  159.     cudaMemcpy(CU_POSZ, POSZ, N * sizeof(float), cudaMemcpyHostToDevice);
  160.     cudaMemcpy(CU_POSR, POSR, 3 * N * sizeof(float), cudaMemcpyHostToDevice);
  161.  
  162.     addKernel <<<nblocks, blocksize>>>(CU_POSM, CU_POSX, CU_POSY, CU_POSZ, CU_POSR);
  163.  
  164.     cudaMemcpy(POSX, CU_POSX, N * sizeof(float), cudaMemcpyDeviceToHost);
  165.     cudaMemcpy(POSY, CU_POSY, N * sizeof(float), cudaMemcpyDeviceToHost);
  166.     cudaMemcpy(POSZ, CU_POSZ, N * sizeof(float), cudaMemcpyDeviceToHost);
  167.     cudaMemcpy(POSR, CU_POSR, 3 * N * sizeof(float), cudaMemcpyDeviceToHost);
  168.  
  169.     cudaFree(CU_POSM);
  170.     cudaFree(CU_POSX);
  171.     cudaFree(CU_POSY);
  172.     cudaFree(CU_POSZ);
  173.     cudaFree(CU_POSR);
  174. }
  175.  
  176. void Timer(int)
  177. {
  178.     //CPU or GPU calc
  179.     if (button == 1)
  180.         GPU_Math();
  181.     else
  182.         OMP_Math();
  183.     //Draw func & call build new frame
  184.     display();
  185.     glutTimerFunc(0, Timer, 0);
  186. }
  187.  
  188. //Point generator
  189. void characters()
  190. {
  191.     for (int i = 0; i < N; i++) {
  192.         POSX[i] = rand() % 1000 - 500;
  193.         POSY[i] = rand() % 1000 - 500;
  194.         POSZ[i] = rand() % 1000 - 500;
  195.         POSM[i] = rand() % 100 + 1;
  196.  
  197.         for (int j = 0; j < i; j++) {
  198.             if ((i != j) && (POSX[i] == POSX[j]) && (POSY[i] == POSY[j]) && (POSZ[i] == POSZ[j]))
  199.                 i--;
  200.         }
  201.     }
  202. }
  203.  
  204. //Select GPU(1) or CPU(2)
  205. void keyboard(unsigned char key, int x, int y)
  206. {
  207.     switch (key)
  208.     {
  209.     case '1': button = 1;
  210.         break;
  211.     case '2': button = 2;
  212.         break;
  213.     }
  214. }
  215.  
  216. void MouseMove(int a, int b)
  217. {
  218.     glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
  219. }
  220.  
  221. //Mouse rotation
  222. void MousePressedMove(int ay, int ax)
  223. {
  224.     glutSetCursor(GLUT_CURSOR_NONE);
  225.     int x_center = (int) h/2, y_center = (int) w/2;
  226.     if (ax != x_center || ay != y_center){
  227.         if (x_center < ax)
  228.             x_angle += 6;
  229.         if (x_center > ax)
  230.             x_angle -= 6;
  231.         if (y_center < ay)
  232.             y_angle += 6;
  233.         if (y_center > ay)
  234.             y_angle -= 6;
  235.         glutWarpPointer(x_center, y_center);
  236.     }
  237. }
  238.  
  239. int main(int argc, char **argv)
  240. {
  241.     srand(time(0));
  242.     setlocale(LC_ALL, "russian");
  243.  
  244.     //Call generator
  245.     characters();
  246.     //CUDA device init
  247.     int nDevices;
  248.     cudaGetDeviceCount(&nDevices);
  249.     for (int i = 0; i < nDevices; i++) {
  250.         cudaDeviceProp prop;
  251.         cudaGetDeviceProperties(&prop, i);
  252.         std::cout << "GPU # " << i;
  253.         std::cout << " - " << prop.name;
  254.     }
  255.     std::cout << "\n\nN: " << N << std::endl << std::endl;
  256.     std::cout << "[1] -- Select GPU\n";
  257.     std::cout << "[2] -- Select CPU\n";
  258.     std::cout << "[Move + click] -- Rotate" << std::endl << std::endl;
  259.  
  260.     //For freeglut
  261.     glutInit(&argc, argv);
  262.     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
  263.     glutInitWindowPosition(100, 100);
  264.     glutInitWindowSize(h, w);
  265.     glutCreateWindow("");
  266.     glutDisplayFunc(display);
  267.     glutTimerFunc(0, Timer, 0);
  268.     glutKeyboardFunc(keyboard);
  269.     glutPassiveMotionFunc(MouseMove);
  270.     glutMotionFunc(MousePressedMove);
  271.     initialization();
  272.     glutMainLoop();
  273.  
  274.     return 0;
  275. }
  276.  
  277. /*
  278. N = 8000
  279. i5-3450 ~1.66 fps
  280. GTX 1050Ti ~79 fps
  281. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement