2017-12-25 38 views
-3

저는 CUDA에 대해 새로운 지식을 가지고 있습니다. CUDA에 관한 일부 NVIDIA 튜터를 읽었으므로 도움이 필요합니다. 다음과 같은 코드가있다 : 당신이 볼 수 있듯이배열을 이용한 CUDA 병렬 작업

//some includes 
#define NUM_OF_ACCOMS 3360 
#define SIZE_RING 16 
#define NUM_OF_BIGRAMMS 256 

//...some code... 
    for (i = 1; i <= SIZE_RING; i++) { 
     for (j = 1; j <= SIZE_RING; j++) { 
      if (j == i) continue; 
      for (k = 1; k <= SIZE_RING; k++) { 
       if (k == j || k == i) continue; 
       accoms_theta[indOfAccoms][0] = i - 1; accoms_theta[indOfAccoms][1] = j - 1; accoms_theta[indOfAccoms][2] = k - 1; 
       accoms_thetaFix[indOfAccoms][0] = i - 1; accoms_thetaFix[indOfAccoms][1] = j - 1; accoms_thetaFix[indOfAccoms][2] = k - 1; 
       results[indOfAccoms][0] = results[indOfAccoms][1] = results[indOfAccoms][2] = 0; 
       indOfAccoms++; 
      } 
     } 
    } 

    for (i = 0; i < SIZE_RING; i++) 
     for (j = 0; j < SIZE_RING; j++) { 
      bigramms[indOfBigramms][0] = i; bigramms[indOfBigramms][1] = j; 
      indOfBigramms++; 
     } 
     for (i = 0; i < NUM_OF_ACCOMS; i++) { 
      thetaArr[0] = accoms_theta[i][0]; thetaArr[1] = accoms_theta[i][1]; thetaArr[2] = accoms_theta[i][2]; 
      d0 = thetaArr[2] - thetaArr[1]; d1 = thetaArr[2] - thetaArr[0]; 
      if (d0 < 0) 
       d0 += SIZE_RING; 
      if (d1 < 0) 
       d1 += SIZE_RING; 
      for (j = 0; j < NUM_OF_ACCOMS; j++) { 
       theta_fixArr[0] = accoms_thetaFix[j][0]; theta_fixArr[1] = accoms_thetaFix[j][1]; theta_fixArr[2] = accoms_thetaFix[j][2]; 
       d0_fix = theta_fixArr[2] - theta_fixArr[1]; d1_fix = theta_fixArr[2] - theta_fixArr[0]; 
       count = 0; 
       if (d0_fix < 0) 
        d0_fix += SIZE_RING; 
       if (d1_fix < 0) 
        d1_fix += SIZE_RING; 
       for (k = 0; k < NUM_OF_BIGRAMMS; k++) { 
        diff0 = subst[(d0 + bigramms[k][0]) % SIZE_RING] - subst[bigramms[k][0]]; 
        diff1 = subst[(d1 + bigramms[k][1]) % SIZE_RING] - subst[bigramms[k][1]]; 

        if (diff0 < 0) 
         diff0 += SIZE_RING; 
        if (diff1 < 0) 
         diff1 += SIZE_RING; 
        if (diff0 == d0_fix && diff1 == d1_fix) 
         count++; 
       } 
       if (max < count) { 
        max = count; 
        results[indResults][0] = max; results[indResults][1] = i; results[indResults][2] = j; 
        count = 0; 
        indResults++; 
       } 
      } 
     } 

, ij 변수 두 가지 사이클이 있습니다. 내가 accoms_theta 에서 각 배열과 조건을 확인 foreach 배열이 필요합니다. (subst은 SIZE_RING 요소가있는 int 배열입니다.) 모든 배열을 검사하기 위해 약 2^30 작업이 필요합니다. 왜냐하면 나는 CUDA에서 새로운 알고리즘을 병렬 처리하는데 도움이 필요하다. 여기

내 장치

GeForce GT730M 
Compute Capability 3.5 
Global Memory 2 GB 
Shared Memory Per Block 48 KB 
Max Threads Per Block 1024 
Number of multiprocessors 2 
Max Threads Dim 1024 : 1024 : 64 
Max Grid Dim 2*(10^9) : 65535 : 65535 

답변

-1

나는 당신이 계산하기 위해 노력하고 무엇이든의 특정 세부 사항에 가지 않을에 대한 몇 가지 정보입니다,하지만 난 제안 당신이 할 수있는 무엇에 대한 것.

CUDA (또는 OpenCL 또는 OpenMP even)에서 직렬 알고리즘을 병렬 처리하는 직접적인 방법은 "루프를 위해 병렬 처리"하는 것입니다. 하나의 스레드가 어떤 인덱스 i의 값을 반복하는 대신에, 다른 GPU 스레드는 i의 다른 값 (또는 i의 여러 값마다 하나의 스레드)에서 작동합니다.

이것은 중첩 루프를 사용하여 수행 할 수 있습니다. 커널 실행 격자의 두 가지 차원에 해당하는 두 개의 인덱스 ij이 있습니다.

그러나 - 데이터 간의 종속성 (예 ij의 각 조합에 대한) 각각의 스레드에 의해 기록/계산되지 위해 존재 -이 '소박'embarrassingly parallel 문제 만 가능하고. 또한 의 데이터가 ij에 대해 중복되는으로 읽거나 인터리브되는 경우 동일한 데이터를 반복적으로 읽지 못하게하여 성능을 저하시키지 않도록주의해야합니다.

이 방법을 시도해보십시오. 실패 할 경우 또는 신청할 수 없다는 결론에 이르면 다른 질문을하십시오. 질문에 대해서는이 질문에 제공하지 않은 Minimal, Complete, Verifiable Example이 필요합니다.