私はcudaを初めて使用し、問題があります。スレッドに同期を入れたいので、syncthreadsを使用してみました。問題は、Visual Studio2010が次のように言っていることです。idetifier__syncthreads()は未定義です...ちなみに私はcuda4.2を使用しています。そこで、代わりにcudaDeviceSynchronize()を使用して、ホストから呼び出すことにしました。私のコードは上記のようなものです(私はあなたに重要な部分だけを送ります):
__global__ void sum( float avg[]){
avg[0]+=1;
avg[1]+=2;
}
int main(){
float avg[2];
float *devAvg;
cudaError_t cudaStatus;
size_t size=sizeof(unsigned char)*2;
cudaStatus = cudaMalloc((void**)&devAvg, size2);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc 2 failed!");
return -1;
}
avg[0]=0;
avg[1]=0;
cudaStatus = cudaMemcpy(devAvg,avg, size, cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
return -1;
}
dim3 nblocks(40,40);
dim3 nthreads(20,20);
sum<<<nblocks,nthreads,msBytes>>>(devAvg);
cudaStatus = cudaDeviceSynchronize();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
}
cudaStatus = cudaMemcpy(avg,devAvg,size,cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy Device to Host failed!");
return -1;}
cout<<"avg[0]="avg[0]<<" avg[1]="<<avg[1]<<endl;
cudaFree devAvg;
return 0;
}
結果はavg[0]= 640.000 avg [1]=1.280.000になるはずだと思いました
しかし、私の結果が異なるだけでなく(これはオーバーフローの問題である可能性があります)、安定していません。たとえば、3つの異なる実行の場合、結果は次のようになります。
avg [0] = 3041 avg [1] = 6604
avg [0] = 3015 avg [1] = 6578
avg [0] = 3047 avg [1] = 6600
では、ここで何が間違っているのでしょうか?それは同期の問題ですか?そしてなぜ__syncthreads()を使用できないのですか?それとも競合状態の問題ですか?
さらに、__ syncthreads()の問題については、私が書いたコードが付属しています。最も単純なものでさえ:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <Windows.h>
// Kernel that executes on the CUDA device
__global__ void square_array(float *a, int N)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx<N) a[idx] = a[idx] * a[idx];
__syncthreads();
}
// main routine that executes on the host
int main(void)
{
float *a_h, *a_d; // Pointer to host & device arrays
const int N = 10; // Number of elements in arrays
size_t size = N * sizeof(float);
a_h = (float *)malloc(size); // Allocate array on host
cudaMalloc((void **) &a_d, size); // Allocate array on device
// Initialize host array and copy it to CUDA device
for (int i=0; i<N; i++) a_h[i] = (float)i;
cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
// Do calculation on device:
int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<< n_blocks, block_size >>> (a_d, N);
// Retrieve result from device and store it in host array
cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
// Print results
for (int i=0; i<N; i++) printf("%d %f\n", i, a_h[i]);
// Cleanup
free(a_h); cudaFree(a_d);
return 0;
}
これは次のように言っています:エラー:識別子 "__syncthreads()"は未定義です
面白い部分は、4.2 CUDA SDKに付属しているサンプルコードでも同じことが起こることです...SDKサンプルには未定義と見なされる関数が多いため、おそらくもっと一般的な間違いです。