【发布时间】:2017-07-23 10:12:31
【问题描述】:
我已经实现了一个矢量点积,如下所示。
它使用 CUDA 7.5 编译,带有 compute_20,sm_20 和 const int THREADS_PER_BLOCK = 16;。
浮点数和双精度数都会发生这种情况。
它在n=368 上有效,但除此之外,结果不正确。我想知道问题出在我的实现代码还是我正在使用的值(请参阅第二个代码,初始化),例如可能是 n=368 之外的添加引入了浮点错误(这可能很奇怪,因为浮点数和双精度数都发生了相同的错误)。
int divUp(int total, int grain) { return (total+grain-1)/grain; }
__device__ __forceinline__ double atomicAdd(double* address, double val)
{
unsigned long long int* address_as_ull = (unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
do
{
assumed = old;
old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val+__longlong_as_double(assumed)));
}
while(assumed!=old);
return __longlong_as_double(old);
}
__device__ __forceinline__ float atomicAdd(float* address, float val)
{
unsigned int *ptr = (unsigned int *)address;
unsigned int old, newint, ret = *ptr;
do {
old = ret;
newint = __float_as_int(__int_as_float(old)+val);
} while((ret = atomicCAS(ptr, old, newint)) != old);
return __int_as_float(ret);
}
template<typename T>
__global__ void vecdotk(const T* a, const T* b, const int n, T* c)
{
__shared__ T temp[THREADS_PER_BLOCK];
int x = threadIdx.x+blockIdx.x*blockDim.x;
if(x==0) c[0] = 0.0;
if(x<n) {temp[threadIdx.x] = a[x]*b[x];
}
else temp[threadIdx.x] = 0.0;
__syncthreads();
if(0==threadIdx.x)
{
T sum = 0.0;
for(int j=0; j<THREADS_PER_BLOCK; ++j)
{
sum += temp[j];
}
atomicAdd(c, sum);
}
}
template<typename T>
void dot(const T* a, const T* b, const int n, T* c)
{
dim3 block(THREADS_PER_BLOCK);
dim3 grid(divUp(n, block.x), 1);
vecdotk<T><<<grid, block>>>(a, b, n, c);
cudaSafeCall(cudaGetLastError());
};
我使用以下两个宿主向量来填充输入设备数组(目前我没有展示它们,因为它们是更大库的一部分)。基本上我想计算平方系列的总和,即
// fill host vectors a and b
for(int i=0; i<n; ++i)
{
h_vec_a[i] = i+1;//__mat_rand();
h_vec_b[i] = i+1;//__mat_rand();
}
【问题讨论】:
标签: cuda dot-product