cuda device 内存丢失

发现一个 cuda 的 bug:

    在 device 端分配一大块内存,然后在 kernel 函数里,每个 thread 往内存的某一个区域里写一些信息,可是发现当初写进去的信息,在读回host 时,一些信息已经丢失。。郁闷啊,郁闷!!

 

分别在 cuda 1.0,2.0,3.0 环境下测试,问题雷同。

测试环境:

显卡: tesla C1060

OS : winxp 32 位

64 位机器

 


代码如下:

// pay attention on "these characters are losing" in function Test_kernel(char* logInfo)

#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <cutil.h>
#define Log 1
#define THREAD_SIZE 1024
#define THREAD_NUM 4

/************************************************************
************/
/* Init CUDA */
/************************************************************
************/
#if __DEVICE_EMULATION__

bool InitCUDA(void){return true;}

#else
bool InitCUDA(void)
{
int count = 0;
int i = 0;

cudaGetDeviceCount(&count);
if(count == 0) {
fprintf(stderr, "There is no device./n");
return false;
}

for(i = 0; i < count; i++) {
cudaDeviceProp prop;
if(cudaGetDeviceProperties(&prop, i) == cudaSuccess) {
if(prop.major >= 1) {
break;
}
}
}
if(i == count) {
fprintf(stderr, "There is no device supporting CUDA./n");
return false;
}
cudaSetDevice(i);

printf("CUDA initialized./n");
return true;
}

#endif


__device__ int sprintf_int(char *s, int v) {
int len=0;
if(v==0) {
s[0]='0';
return (len=1);
}
if(v<0) {
s[len++]='-';
v=-v;
}
unsigned int base;
for(base=1000000000; base>0; base/=10) if((unsigned int)v>=base) break;
while(base>0) {
s[len++]='0'+(v/base)%10;
base/=10;
}
return len;
}
__device__ int sprintf_str(char *s, char *s2) {
int i;
for(i=0; s2[i]; i++) s[i]=s2[i];
return i;
}




__global__ void Test_kernel(char* logInfo)
{
int threadId = threadIdx.x;
char* pLog = logInfo + threadId*THREAD_SIZE;
int oI = 0;

if(Log && oI<THREAD_SIZE-20) oI+=sprintf_str(pLog+oI,"=============threadid= ");
if(Log && oI<THREAD_SIZE-20) oI+=sprintf_int(pLog+oI,threadId);
if(Log && oI<THREAD_SIZE-20) oI+=sprintf_str(pLog+oI,"= these characters are losing/n");

if(Log && oI<THREAD_SIZE-20) oI+=sprintf_str(pLog+oI,"123456/n");
if(Log && oI<THREAD_SIZE-20) oI+=sprintf_str(pLog+oI,"123456/n");


if(Log && oI<THREAD_SIZE-20) oI+=sprintf_str(pLog+oI,"************** end thread logsize= ");
if(Log && oI<THREAD_SIZE-20) oI+=sprintf_int(pLog+oI,oI);
if(Log && oI<THREAD_SIZE-20) oI+=sprintf_str(pLog+oI,"************/n");

}


extern "C"
void TestCuda(char* h_logInfo,
long logSize)
{
char *d_logInfo;

if(Log) CUDA_SAFE_CALL(cudaMalloc((void**)&d_logInfo,logSize));
if(Log) CUDA_SAFE_CALL(cudaMemcpy(d_logInfo,h_logInfo,logSize,cudaMe
mcpyHostToDevice));

Test_kernel<<<1,THREAD_NUM>>>(d_logInfo);

if(Log) CUDA_SAFE_CALL(cudaMemcpy(h_logInfo,d_logInfo,logSize,cudaMe
mcpyDeviceToHost));
if(Log) CUDA_SAFE_CALL(cudaFree(d_logInfo));
}


char* compress(char* str,char delChar)
{
int i = 0;
int j = 0;
while(str[j] && str[j++] != delChar);
j--;
for(i=j;str[i];i++)
{
if(str[i] != delChar)
str[j++]=str[i];
}
str[j]=0;
return str;
}


/************************************************************
************/
/* HelloCUDA */
/************************************************************
************/
int main(int argc, char* argv[])
{

if(!InitCUDA()) {
return 0;
}

long logSize = sizeof(char)* THREAD_SIZE * THREAD_NUM;
char * logInfo = (char*)malloc(logSize);
memset(logInfo,'@',logSize);
TestCuda(logInfo,logSize);

printf(compress(logInfo,'@'));
CUT_EXIT(argc, argv);

return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
CUDA共享内存是一种位于GPU上的高速存,可以用于在同一个线程块内的线程之间共享数据。使用共内存可以显著提内存访问的效,并且减少对全局内存访问次数。 以下使用CUDA共享内存的一般步: 1. 声明共内存:在GPU核函数中,可以使用`__shared__`关键字来声明共享内存。共享内存的大小需要在编译时确定,并且是所有线程块中的线程共享的。 ```cuda __shared__ float sharedData[SIZE]; ``` 2. 将数据从全局内存复制到共享内存:在GPU核函数中,使用线程块中的线程来将数据从全局内存复制到共享内存中。可以使用线程块索引和线程索引来确定数据的位置。 ```cuda int tid = threadIdx.x; int blockId = blockIdx.x; int index = blockId * blockDim.x + tid; sharedData[tid] = globalData[index]; ``` 3. 同步线程块:在将数据复制到共享内存后,需要使用`__syncthreads()`函数来同步线程块中的线程。这样可以确保所有线程都已经将数据复制到共享内存中。 ```cuda __syncthreads(); ``` 4. 使用共享内存:一旦所有线程都已经将数据复制到共享内存中,可以使用共享内存进行计算。由于共享内存位于GPU的高速缓存中,所以访问速度较快。 ```cuda sharedData[tid] += 1.0f; ``` 5. 将数据从共享内存复制回全局内存:在计算完成后,可以使用线程块中的线程将数据从共享内存复制回全局内存。 ```cuda globalData[index] = sharedData[tid]; ``` 需要注意的是,共享内存的大小是有限的,不同的GPU架构及型号都有不同的限制。因此,在使用共享内存时,需要确保不超过设备的限制,并且合理地利用共享内存,以提高性能。此外,需要注意线程同步的位置和使用方法,以避免数据竞争和错误的结果。 以上是使用CUDA共享内存的基本步骤,具体的实现方式会根据具体问题而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值