Итак, основная идея задачи состоит в том, чтобы вычислить среднее количество нескольких изображений, у меня это работает обычным способом, поэтому я подумал, что я дам ему возможность использовать CUDA, но, к сожалению, то, что я получаю на выходе, - это первое изображение вместо среднего. (Внутри ядра я также попытался установить некоторые пиксели в 0, чтобы убедиться, что что-то не происходит, но не повезло ..) распределениеЯдро CUDA не обновляет выходные данные
////My kernel:
//nImages - number of images in the memory
//nBytes - number of pixels*color per image (also it's a size of dataOut)
//nImages*nBytes gives us the size of dataIn
//nBatch - dataIn has 1 milion bytes per image, we run in 6144 threads, so we need 163 batches to calc the whole dataOut
__global__
void avg_arrays(unsigned char* cuDataIn, unsigned char* cuDataOut, int nImages, int nBytes, int nBatch)
{
//get the position of the correct byte
int j = threadIdx.x + nBatch;
//if we're outside of image then give up
if(j >= nBytes) return;
//proceed averaging
long lSum = 0;
for(int i=0; i < nImages; ++i)
lSum += cuDataIn[i*nBytes + j];
lSum = lSum/nImages;
cuDataOut[j] = lSum;
}
памяти и т.д.
unsigned char* dataIn = 0;
unsigned char* dataOut= 0;
// Allocate and Transfer memory to the devicea
gpuErrchk(cudaMalloc((void**)&dataIn, nPixelCountBGR * nNumberOfImages * sizeof(unsigned char))); //dataIn
gpuErrchk(cudaMalloc((void**)&dataOut, nPixelCountBGR * sizeof(unsigned char))); //dataOut
gpuErrchk(cudaMemcpy(dataIn, bmps, nPixelCountBGR * nNumberOfImages * sizeof(unsigned char), cudaMemcpyHostToDevice)); //dataIn
gpuErrchk(cudaMemcpy(dataOut, basePixels, nPixelCountBGR * sizeof(unsigned char), cudaMemcpyHostToDevice)); //dataOut
// Perform the array addition
dim3 dimBlock(N);
dim3 dimGrid(1);
//do it in batches, unless it's possible to run more threads at once, anyway N is a number of max threads
for(int i=0; i<nPixelCountBGR; i+=N){
cout << "Running with: nImg: "<< nNumberOfImages << ", nPixBGR " << nPixelCountBGR << ", and i = " << i << endl;
avg_arrays<<<dimGrid, dimBlock>>>(dataIn, dataOut, nNumberOfImages, nPixelCountBGR, 0);
}
// Copy the Contents from the GPU
gpuErrchk(cudaMemcpy(basePixels, dataOut, nPixelCountBGR * sizeof(unsigned char), cudaMemcpyDeviceToHost));
gpuErrchk(cudaFree(dataOut));
gpuErrchk(cudaFree(dataIn));
Проверка ошибок не приносит любые сообщения, весь код работает гладко, все, что я получаю в конце, - это точная копия первого изображения.
Только в том случае, если кто-то должен здесь какая-то консольная выход:
Running with: nImg: 29, nPixBGR 1228800, and i = 0
...
Running with: nImg: 29, nPixBGR 1228800, and i = 1210368
Running with: nImg: 29, nPixBGR 1228800, and i = 1216512
Running with: nImg: 29, nPixBGR 1228800, and i = 1222656
Time of averaging: 0.219
Основная проблема заключается в том, что вы усредняете часть 'i = 0' снова и снова. –
Джеффри, ты можешь сказать что-то еще? Каждый раз, когда я начинаю усреднять для другой партии 6144 пикселей и просматриваю все изображения, хранящиеся в cuDataIn (первое изображение начинается с 0, второе с 1228800 ..). Внутри ядра я пытаюсь пройти все изображения, которые я сохраняю в памяти (29)? –
Где в вашем цикле вы фактически используете 'i'? –