編集 3: グローバル メモリ内のプライベートな場所を読み書きするには、各スレッドが必要です。以下に、私の問題を示す実際のコードを投稿します。以下に、関連する主な変数と構造をリストします。
変数:
srcArr_h
(ホスト) -->srcArr_d
(デバイス) : 範囲 [0,COLORLEVELS
]のランダムな float の配列ARRDIM
auxD
(device) : 次元の配列ARRDIM
*ARRDIM
最終結果をデバイスに保持auxH
(ホスト) : 次元の配列ARRDIM
*ARRDIM
ホストに最終結果を保持c_glob_d
COLORLEVELS
(device) :スレッドごとに float のプライベートな場所を予約する配列で、サイズはnum_threads
*で指定されますCOLORLEVELS
idx
(device) : 現在のスレッドの識別番号
私の問題: カーネルでは、c_glob[idx]
各値ic
( ic
∈ [0, COLORLEVELS
])を更新しますc_glob[idx][ic]
。に格納されc_glob[idx][COLORLEVELS]
ている最終結果を計算するために使用 します。私の問題は、私の最終結果が間違っていることです。auxH にコピーされた結果は、予想よりも少なくとも 1 桁大きい数値、または操作がオーバーフローする可能性が高いことを示唆する奇妙な数値を取得することを示しています。ヘルプ: 何が間違っていますか? 各スレッドがグローバル メモリ内の各プライベート ロケーションを読み書きできるようにするにはどうすればよいですか? 現在、 = 512 でデバッグしていますが、私の目標は~ 10^4 で動作させることです。したがって、g0
auxD
ARRDIM
ARRDIM
c_glob
10^4*10^4 スレッドの配列)。実行ごとに許可されるスレッドの総数に問題があると思います..だから、私の問題に対する他の解決策を提案できるかどうか疑問に思っていました.
ありがとうございました。
#include <string>
#include <stdint.h>
#include <iostream>
#include <stdio.h>
#include "cuPrintf.cu"
using namespace std;
#define ARRDIM 512
#define COLORLEVELS 4
__global__ void gpuKernel
(
float *sa, float *aux,
size_t memPitchAux, int w,
float *c_glob
)
{
float sc_loc[COLORLEVELS];
float g0=0.0f;
int tidx = blockIdx.x * blockDim.x + threadIdx.x;
int tidy = blockIdx.y * blockDim.y + threadIdx.y;
int idx = tidy * memPitchAux/4 + tidx;
for(int ic=0; ic<COLORLEVELS; ic++)
{
sc_loc[ic] = ((float)(ic*ic));
}
for(int is=0; is<COLORLEVELS; is++)
{
int ic = fabs(sa[tidy*w +tidx]);
c_glob[tidy * COLORLEVELS + tidx + ic] += 1.0f;
}
for(int ic=0; ic<COLORLEVELS; ic++)
{
g0 += c_glob[tidy * COLORLEVELS + tidx + ic]*sc_loc[ic];
}
aux[idx] = g0;
}
int main(int argc, char* argv[])
{
/*
* array src host and device
*/
int heightSrc = ARRDIM;
int widthSrc = ARRDIM;
cudaSetDevice(0);
float *srcArr_h, *srcArr_d;
size_t nBytesSrcArr = sizeof(float)*heightSrc * widthSrc;
srcArr_h = (float *)malloc(nBytesSrcArr); // Allocate array on host
cudaMalloc((void **) &srcArr_d, nBytesSrcArr); // Allocate array on device
cudaMemset((void*)srcArr_d,0,nBytesSrcArr); // set to zero
int totArrElm = heightSrc*widthSrc;
for(int ic=0; ic<totArrElm; ic++)
{
srcArr_h[ic] = (float)(rand() % COLORLEVELS);
}
cudaMemcpy( srcArr_d, srcArr_h,nBytesSrcArr,cudaMemcpyHostToDevice);
/*
* auxiliary buffer auxD to save final results
*/
float *auxD;
size_t auxDPitch;
cudaMallocPitch((void**)&auxD,&auxDPitch,widthSrc*sizeof(float),heightSrc);
cudaMemset2D(auxD, auxDPitch, 0, widthSrc*sizeof(float), heightSrc);
/*
* auxiliary buffer auxH allocation + initialization on host
*/
size_t auxHPitch;
auxHPitch = widthSrc*sizeof(float);
float *auxH = (float *) malloc(heightSrc*auxHPitch);
/*
* kernel launch specs
*/
int thpb_x = 16;
int thpb_y = 16;
int blpg_x = (int) widthSrc/thpb_x;
int blpg_y = (int) heightSrc/thpb_y;
int num_threads = blpg_x * thpb_x + blpg_y * thpb_y;
/*
* c_glob: array that reserves a private location of COLORLEVELS floats for each thread
*/
int cglob_w = COLORLEVELS;
int cglob_h = num_threads;
float *c_glob_d;
size_t c_globDPitch;
cudaMallocPitch((void**)&c_glob_d,&c_globDPitch,cglob_w*sizeof(float),cglob_h);
cudaMemset2D(c_glob_d, c_globDPitch, 0, cglob_w*sizeof(float), cglob_h);
/*
* kernel launch
*/
dim3 dimBlock(thpb_x,thpb_y, 1);
dim3 dimGrid(blpg_x,blpg_y,1);
gpuKernel<<<dimGrid,dimBlock>>>(srcArr_d,auxD, auxDPitch, widthSrc, c_glob_d);
cudaThreadSynchronize();
cudaMemcpy2D(auxH,auxHPitch,
auxD,auxDPitch,
auxHPitch, heightSrc,
cudaMemcpyDeviceToHost);
cudaThreadSynchronize();
float min = auxH[0];
float max = auxH[0];
float f;
string str;
for(int i=0; i<widthSrc*heightSrc; i++)
{
if(min > auxH[i])
min = auxH[i];
if(max < auxH[i])
max = auxH[i];
}
cudaFree(srcArr_d);
cudaFree(auxD);
cudaFree(c_glob_d);
}