2017-12-25 28 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変数を持つ2つの主要なサイクルがあります。私はaccoms_thetaからforeach配列が必要ですaccoms_thetaFixから各配列の状態を確認します。 (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の偶数)でシリアルアルゴリズムを並列化する直接的なアプローチは、「ループの並列化」することです。代わりに、いくつかの指標iの値を超えるシングルスレッド反復を持つの意味CUDAの文脈では、異なるGPUスレッドが異なるiの値( - iのすべてのいくつかの値に1つのスレッドまたは)上で動作しています。

これはネストされたループで行うことができます。カーネル起動グリッドの2つのディメンションに対応する2つのインデックスijがあります。

ただし - (例えばijの組み合わせごとに)各スレッドによって書き込まれ/計算されるデータとの間には依存関係が存在しない - これは「単純」embarrassingly parallel問題に対してのみ可能であること。また、が異なるij重複のためを読んだか、インタリーブされたデータは、さらに注意がパフォーマンスを低下させる、同じデータを繰り返し読み防止するために必要とされる場合。

この方法をお試しください。失敗した場合、または適用できないという結論に達した場合は、別の質問をしてください。その質問では、この質問のために提供していないMinimal, Complete, Verifiable Exampleが必要です。

関連する問題