2012-03-29 26 views
3

Ich habe ein Problem mit einigen für verschachtelte Schleifen, die ich von C/C++ in CUDA konvertieren muss. Grundsätzlich habe ich 4 für verschachtelte Schleifen, die sich das gleiche Array teilen und Bit-Shift-Operationen durchführen.Für verschachtelte Schleifen mit CUDA

#define N 65536 

// ---------------------------------------------------------------------------------- 

int a1,a2,a3,a4, i1,i2,i3,i4; 

int Bit4CBitmapLookUp[16] = {0, 1, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15}; 

int _cBitmapLookupTable[N]; 

int s = 0; // index into the cBitmapLookupTable 

for (i1 = 0; i1 < 16; i1++) 
{ 
    // first customer 
    a1 = Bit4CBitmapLookUp[i1] << 12; 

    for (i2 = 0; i2 < 16; i2++) 
    { 
     // second customer 
     a2 = Bit4CBitmapLookUp[i2] << 8; 

     for (i3 = 0; i3 < 16; i3++) 
     { 
      // third customer 
      a3 = Bit4CBitmapLookUp[i3] << 4; 

      for (i4 = 0;i4 < 16;i4++) 
      { 
       // fourth customer 
       a4 = Bit4CBitmapLookUp[i4]; 

       // now actually set the sBitmapLookupTable value 
       _cBitmapLookupTable[s] = a1 | a2 | a3 | a4; 

       s++; 

      } // for i4 
     } // for i3 
    } // for i2 
} // for i1 

Dies ist der Code, den ich in CUDA konvertieren sollte. Ich habe verschiedene Wege ausprobiert, aber jedesmal habe ich die falsche Ausgabe. Hier poste ich meine Version von CUDA-Konvertierung (das Stück vom Kernel Teil)

#define N 16 

//---------------------------------------------------------------------------------- 

// index for the GPU 
int i1 = blockDim.x * blockIdx.x + threadIdx.x; 
int i2 = blockDim.y * blockIdx.y + threadIdx.y; 
int i3 = i1; 
int i4 = i2; 

__syncthreads(); 
for(i1 = i2 = 0; i1 < N, i2 < N; i1++, i2++) 
{ 
    // first customer 
    a1 = Bit4CBitmapLookUp_device[i1] << 12; 

    // second customer 
    a2 = Bit4CBitmapLookUp_device[i2] << 8; 

    for(i3 = i4 = 0; i3 < N, i4 < N; i3++, i4++){ 
     // third customer 
     a3 = Bit4CBitmapLookUp_device[i3] << 4; 

     // fourth customer 
     a4 = Bit4CBitmapLookUp_device[i4]; 

     // now actually set the sBitmapLookupTable value 
     _cBitmapLookupTable[s] = a1 | a2 | a3 | a4; 
     s++; 
    } 
} 

Ich bin ganz neu in CUDA und ich lerne immer noch, aber wirklich kann ich keine Lösung für alle, die verschachtelten Schleifen finden . Vielen Dank im Voraus.

+1

Hinweis: Sie initialisieren die Variablen 'i1' ...' i4' auf Werte, die niemals verwendet werden. – leftaroundabout

+0

dies Siehe -> http://stackoverflow.com/questions/5306117/cuda-kernel-nested-for-loop http://stackoverflow.com/questions/6479715/nested-loops-to-cuda http://stackoverflow.com/questions/9527026/cumulative-sum-in-two-dimensions-on-array-in-nested-loop-cuda-implementation –

Antwort

2

Wie links bereits angedeutet, gibt es ein Problem mit der Initialisierung. Was würde ich empfehlen, dass Sie das Programm neu zu schreiben als

int i1 = blockDim.x * blockIdx.x + threadIdx.x; 
int i2 = blockDim.y * blockIdx.y + threadIdx.y; 
int i3; 
int i4; 

while(i1 < N && i2 < N){ 
    a1 = ..; 
    a2 = ..; 
    for(i3 = i4 = 0; i3 < N, i4 < N; i3++, i4++){ 
    // third customer 
    a3 = Bit4CBitmapLookUp_device[i3] << 4; 

    // fourth customer 
    a4 = Bit4CBitmapLookUp_device[i4]; 

    // now actually set the sBitmapLookupTable value 
    _cBitmapLookupTable[s] = a1 | a2 | a3 | a4; 
    s ++; 
    } 
    s += blockDim.x*gridDim.x*blockDim.y*gridDim.y; 
    i1 += blockDim.x*gridDim.x; 
    i2 += blockDim.y*gridDim.y; 
} 

folgt Ich habe es nicht getestet, so kann ich nicht garantieren, dass der Indizes richtig ist. Das überlasse ich dir.

Ein bisschen mehr Erklärung: Im obigen Code sind nur die Schleifen über i1 und i2 parallelisiert. Dies setzt voraus, dass N ** 2 groß genug ist im Vergleich zu der Anzahl der Kerne, die Sie auf Ihrer GPU haben. Wenn dies nicht der Fall ist. Alle vier Schleifen müssen parallelisiert werden, um ein effizientes Programm zu erhalten. Der Ansatz wäre dann ein bisschen anders.

+0

Aber was ist mit den Indizes i3 und i4? Soll ich sie als normale Ganzzahlen deklarieren? – davideberdin

+0

Tut mir leid, ich dachte, es war klar, dass sie normale Ganzzahlen sein sollten. Meine Antwort wurde aktualisiert. – Azrael3000

Verwandte Themen