2016-06-29 18 views
0

私はC++コードをCudaコードに変換しようとしています。次のトリプルネストされたforループは、さらにOpenGLレンダリングのための配列を埋めています(私は単純に座標頂点配列):Cudaトリプルネストループ用の割り当て

私はより高速な操作をしたいので、上記のような操作のためにCudaを使用します。最も外側のループの反復ごとに1つのブロックを作成したいと思います。内部ループは170 * 170 = 28900回の反復の反復を持つので、最も内側のループ反復に1つのスレッドを割り当てます。

__global__ void mykernel(int k, float *buffer) { 
int idz=blockIdx.x; 
int idx=threadIdx.x; 
int idy=threadIdx.y; 

buffer[k]=idx+0.5; 
buffer[k+1]=idy+0.5; 
buffer[k+2]=idz+0.5; 
k+=3; 

} 

int main(void) { 
    int dim=3*170*170*263; 
    float* g_vertex_buffer_data_2 = new float[dim]; 
    float* g_vertex_buffer_data_3; 
    int i=0; 

    HANDLE_ERROR(cudaMalloc((void**)&g_vertex_buffer_data_3, sizeof(float)*dim)); 

    dim3 dimBlock(170, 170); 

    dim3 dimGrid(263); 

    mykernel<<<dimGrid, dimBlock>>>(i, g_vertex_buffer_data_3); 

    HANDLE_ERROR(cudaMemcpy(&g_vertex_buffer_data_2,g_vertex_buffer_data_3,sizeof(float)*dim,cudaMemcpyDeviceToHost)); 

    for(int j=0;j<100;j++){ 
    printf("g_vertex_buffer_data_2[%d]=%f\n",j,g_vertex_buffer_data_2[j]); 
    } 
    cudaFree(g_vertex_buffer_data_3); 

    return 0; 

} 

私はsegmenationフォールトを取得して起動しようとすると:私は(それは私がクーダを使用する方法を理解するために作られただけの小さなプログラムです)この中のC++コードを変換します。私は何が間違っているのか知っていますか? 問題は、threadIdx.xとthreadIdx.yが同時に成長しているのに対し、threadIdx.xを内側に、threadIdx.yを外側にしたいと思っています。

答えて

4

あり、ここでたくさん間違っているが、セグメンテーションフォルトのソースはこれです:あなたはあなたのことを修正したら

cudaMemcpy(&g_vertex_buffer_data_2,g_vertex_buffer_data_3, 
       sizeof(float)*dim,cudaMemcpyDeviceToHost); 

あなたのどちらかが

cudaMemcpy(&g_vertex_buffer_data_2[0],g_vertex_buffer_data_3, 
       sizeof(float)*dim,cudaMemcpyDeviceToHost); 

または

cudaMemcpy(g_vertex_buffer_data_2,g_vertex_buffer_data_3, 
       sizeof(float)*dim,cudaMemcpyDeviceToHost); 

をしたいですカーネルが実際に無効な起動エラーで起動することはありません。これは、ブロックサイズが(170,170)であるためです。 CUDAには現在のすべてのハードウェアでブロックあたり1024スレッドの制限があります。

コードに他の問題がある可能性があります。私はこれらの2つを見つけた後、探して止まった。

+0

私は最初のことを編集しました、ありがとうございます!今私は2番目のものを試して、私はブロックごとにグリッドとスレッドごとのブロックの数を設定する正しい方法を見つける必要があります。私のトリプルネストループでは、g_vertex_buffer_data_3のインデックスとしてthreadsIdとblockIdを使うべきですか?または、すべてのループで増加する異なるインデックスを使うべきですか? –

+0

このような大きなデータセットを使用する代わりに、他の問題を修正するために、より小さなデータセットから開始することができます。たとえば、k + = 3は期待したことをしていない、バッファオーバーフローをテストし、g_vertex_buffer_data_2が漏れています。 その後、たとえば次のことができます。 HWの制限を回避するために、データセット全体を分割してCUDAカーネルを複数回コールします。しかし、まずは論理的な権利を得てください。 –

+0

ありがとう! CUDAでk + = 3をどうすればいいですか?私は、C + +でk + = 3を行うことをCudaに命じるにはどうすればいいのですか? –

関連する問題