4 * 4 어레이에 8 * 8 어레이의 블록 평균을 찾으려고합니다. 다음과 같은 내용이 있습니다 : CUDA 블록 평균
저는 현재 프로그램을 실행할 때마다 각 스레드가 읽는 값이 달라지는 경쟁 조건 유형 수수께끼에 갇혀 있습니다. 지금 당장 나의 유일한 관심사는 모든 블록 요소를 함께 추가하는 것입니다. 나중에 그 합계를 나눌 것입니다. 이것은 내 코드입니다. 나는 (내 배열이 모든 잘못된 생각하지만 난 두 차원 하나의 동적 공간을 충당 그냥 드릴 수 없습니다)에게 제발 처음부터 잘못된 접근 방식을 사용하고, 그래서 만약
#include <stdio.h>
#include<math.h>
const int MAIN_SIZE = 8;
const int RESULT_SIZE = 4;
typedef int mainArray[MAIN_SIZE];
typedef int resultArray[RESULT_SIZE];
__global__ void computeMean(mainArray *main, resultArray *result) {
int mColumn = blockIdx.x * blockDim.x + threadIdx.x;
int mRow = blockIdx.y * blockDim.y + threadIdx.y;
if (mRow >= MAIN_SIZE || mColumn >= MAIN_SIZE)
return;
// real calculation
int rRow = std::floor(static_cast<float>(mRow/2)),
rColumn = std::floor(static_cast<float>(mColumn/2));
int x = result[rRow][rColumn] + main[mRow][mColumn];
result[rRow][rColumn] += x;
printf("Adding %d on %d %d at location %d %d; new value: %d\n", main[mRow][mColumn], mRow, mColumn, rRow, rColumn, result[rRow][rColumn]);
}
int main() {
mainArray *hMain, *dMain;
resultArray *hResult, *dResult;
size_t mSize = MAIN_SIZE * MAIN_SIZE * sizeof(int*);
size_t rSize = RESULT_SIZE * RESULT_SIZE * sizeof(int*);
hMain = (mainArray *) malloc (mSize);
hResult = (resultArray *) malloc (rSize);
// populate arrays
int k = 0;
for(int i = 0; i < MAIN_SIZE; i++) {
for(int j = 0; j < MAIN_SIZE; j++) {
hMain[i][j] = ++k;
}
}
memset(hResult, 0, rSize);
printf("main\n");
for(int i = 0; i < MAIN_SIZE; i++) {
for(int j = 0; j < MAIN_SIZE; j++) {
printf("%d ", hMain[i][j]);
}
printf("\n");
}
printf("result\n");
for(int i = 0; i < RESULT_SIZE; i++) {
for(int j = 0; j < RESULT_SIZE; j++) {
printf("%d ", hResult[i][j]);
}
printf("\n");
}
// Allocate memory on device
cudaMalloc(&dMain, mSize);
cudaMalloc(&dResult, rSize);
// Do memcopies to GPU
cudaMemcpy(dMain, hMain, mSize, cudaMemcpyHostToDevice);
cudaMemcpy(dResult, hResult, rSize, cudaMemcpyHostToDevice);
dim3 block(1, 1);
dim3 grid ((MAIN_SIZE + block.x - 1)/block.x, (MAIN_SIZE + block.y - 1)/block.y);
computeMean<<<grid, block>>>(dMain, dResult);
// Do memcopies back to host
cudaMemcpy(hMain, dMain, mSize, cudaMemcpyDeviceToHost);
cudaMemcpy(hResult, dResult, rSize, cudaMemcpyDeviceToHost);
// validate
if (cudaGetLastError() != cudaSuccess) {printf("cuda error\n"); return -1;}
printf("success!\n");
for(int i = 0; i < RESULT_SIZE; i++) {
for(int j = 0; j < RESULT_SIZE; j++) {
printf("%d ", hResult[i][j]);
}
printf("\n");
}
free(hMain);
free(hResult);
cudaFree(dMain);
cudaFree(dResult);
return 0;
}
나는 CUDA에 현재 새로운 오전 . 미리 감사드립니다.
'결과'에서 같은 위치에 여러 개의 스레드를 읽고 쓸 수 있습니다. 여러 종류의 위험 요소가 여기에 있습니다. CUDA 스레드 병렬 아키텍처는 이러한 문제를 자동으로 해결하지 않습니다. (예 : [고전적인 병렬 감소] (http://developer.download.nvidia.com/assets/cuda/files/reduction.pdf) 기법을 사용하여) 충돌하지 않은 접근을 준비하거나 [atomics] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions)를 참조하십시오. –
또한, 이것은 :'mRow/2'는 정수 나누기입니다. 기간. 결과에 대한 정적 캐스트와 'floor'연산을 수행하는 것은 의미없는 낭비적인 노력의 무리입니다. 적절한 부동 소수점 바닥을 원한다면, 나누기를하기 전에 인수 중 하나를'float' **로 캐스팅해야합니다. –
@RobertCrovella : OP 질문에 답하셨습니다. 대답을 해 주실 것입니다. – einpoklum