-1

配列の最大値を見つけようとしています.CUDA Maximum Reduction Algorithm Not Workingの助けを借りました。独自の変更を行います。ただし、16個のデータに対して実行しています。カーネル コードでは、共有メモリが最初の 4 データのみをコピーすることがわかりました。残りは失われます。2 つの cuPrintf..1st printf を配置すると、データが共有メモリにあることがわかります。しかし、2 番目の cuPrintf は __syncthreads の直後にあり、それはスレッド ID 4 の単語から 0 を示しています.. pls help #include #include #include #include #include #include "cuPrintf.cu" #include "cuPrintf.cuh"

__device__ float MaxOf2(float a, float b)
{
    if(a > b)   return a;
    else            return b;
}

__global__ void findMax(int size,float *array_device , float *outPut)
{
    extern __shared__ float sdata[];
    int tid =  threadIdx.x;
    int i = blockIdx.x*blockDim.x + threadIdx.x;

   if(i< size)
   {
    sdata[tid] = array_device[i];
    cuPrintf(" array_d[%d]===%f, sdata[%d]===%f\n ",i,array_device[i],tid,sdata[tid]);
    __threadfence();

    }
    __syncthreads();

    if(tid<size) 
        cuPrintf(" array_d[%d]===%f, sdata[%d]===%f\n ",i,array_device[i],tid,sdata[tid]);

    for ( int s=blockDim.x/2; s>0; s=s>>1)//s=blockDim.x/2
    {   
        if (tid < s) 
        {   
            sdata[tid]= MaxOf2(sdata[tid],sdata[tid+s]);

        }

        __syncthreads();
   }
   if (tid == 0) outPut[blockIdx.x] = sdata[0];

}

 int main()
{
    long double M = pow(2,20);
    long double N = 2;
    int noThreadsPerBlock = 512 ;
    printf("\n Provide the array Size N.(array will be of size N * 2^20 ) :-");
    scanf("%Lf",&N);
    long int size = 16;
    int numOfBlock = (int)size /noThreadsPerBlock + 1;
    printf("\n num of blocks==%ld",numOfBlock);

    float *array_device , *outPut;
    float array_host[]={221,100,2,340,47,36,500,1,33,4460,5,6,7,8,9,11};
    cudaMalloc((void **)&array_device, size*sizeof(float));
    cudaMalloc((void **)&outPut, size*sizeof(float));
    cudaError_t error0 = cudaGetLastError();
    printf("\n 0CUDA error: %s\n", cudaGetErrorString(error0));
    printf("size===%ld",size);

    cudaMemcpy(array_device, array_host, size*sizeof(float), cudaMemcpyHostToDevice);
    cudaError_t error1 = cudaGetLastError();
    printf("\n1CUDA error: %s\n", cudaGetErrorString(error1));


    while(size>1 )
    {
        cudaPrintfInit();
        findMax<<< numOfBlock,noThreadsPerBlock>>>(size,array_device, outPut);cudaPrintfDisplay(stdout, true);
       cudaPrintfEnd();
       cudaError_t error2 = cudaGetLastError();
       printf("   2CUDA error: %s\n", cudaGetErrorString(error2));
       cudaMemcpy(array_device, outPut, size*sizeof(float), cudaMemcpyDeviceToDevice);
       size = numOfBlock;
       printf("\n ****size==%ld\n",size);
       numOfBlock = (int)size /noThreadsPerBlock + 1;
   }

     cudaMemcpy(array_host, outPut, size*sizeof(float), cudaMemcpyDeviceToHost);
     cudaError_t error3 = cudaGetLastError();
    printf("\n3CUDA error: %s\n", cudaGetErrorString(error3));
    for(int i=0;i<size;i++)
          printf("\n index==%d ;data=%f ",i,array_host[i]);
    return 0;
 }
4

1 に答える 1

3

リクエストに応じて、コメントを回答として投稿しています。

まず、カーネルの起動時に共有メモリの動的サイズを指定していません。次のようになります。 findMax<<< numOfBlock,noThreadsPerBlock,sizeof(float)*noThreadsPerBlock>>>

if(tid<size)次に、 secondの条件の背後にある概念は何でしたcuPrintfか? プログラムの出力を提供することも役立ちます。

于 2013-08-30T12:50:11.753 に答える