GTX卡真的会算错么?

目前使用的gtx 680没有问题,运行几个小时都不会错。换成titan之后,有极低的概率会算错。
我的kernel起了8000个线程,一次运行时间大约100ms, 循环运行同一个kernel。大约几十秒就会出错一次。而且只有一两个线程出错,其他线程都是对的。
同样的程序680是没错的,怀疑是硬件算错了。

LZ您好,您的TITAN固然属于geforce产品线,但是您的GTX 680一样是geforce产品线的。如果您认为geforce系列的可靠性不足以满足您的要求,那么两者应该都是不满足的,请立即更换telsa卡。

以及无法评价您的结果,您既没有分析您代码可能的问题之处,也没有给出“算错”的定义和判别标准。

以及,一般来说,硬件出问题的概率极低,至少远低于人为错误率。

一般官方都会推荐专门的计算卡,但谁也没见过geforce算错过。

那您还在1#怀疑?

请不要怀疑你的显卡。显卡出错的概率远远小于人为错误。大量先例告诉表明,计算精度以及计算结果得错误,最终来源都是程序bug。

我知道硬件出错的概率非常非常小,只是代码写的好纠结。
对于我的kernel,titan比gtx680快70%。但是因为这一个问题解决不了,还是不能用,太可惜了。

我再找找问题吧,估计这样的事情大家也应该很少遇到

你可以贴代码/部分代码,尤其是内核和内核调用的代码,这样大家可以帮你找bug。

这个是内核函数和C++之间的接口函数,这个函数调用kernel,c++调用这个函数。
kernel的函数太长,贴出来也没啥价值。

bool XXX_Ckernel(unsigned int *e,unsigned int *r,unsigned int *s,unsigned int *xa, unsigned int ya,unsigned char flag,unsigned int threadnum)
{
static int init=0;
static unsigned int *ge,*gr,*gs,*gxa,*gya;
static unsigned char *gflag;

if(init==0)
{
cudaMalloc((void**) &ge, sizeof(int) * 8THREAD);
cudaMalloc((void**) &gr, sizeof(int) * 8
THREAD);
cudaMalloc((void**) &gs, sizeof(int) * 8THREAD);
cudaMalloc((void**) &gxa, sizeof(int) * 8
THREAD);
cudaMalloc((void**) &gya, sizeof(int) * 8*THREAD);
cudaMalloc((void**) &gflag, sizeof(char) *THREAD);

init =1;

}
cudaMemcpy(ge, e, sizeof(int) * 8THREAD, cudaMemcpyHostToDevice);
cudaMemcpy(gr, r, sizeof(int) * 8
THREAD, cudaMemcpyHostToDevice);
cudaMemcpy(gs, s, sizeof(int) * 8THREAD, cudaMemcpyHostToDevice);
cudaMemcpy(gxa, xa, sizeof(int) * 8
THREAD, cudaMemcpyHostToDevice);
cudaMemcpy(gya, ya, sizeof(int) * 8*THREAD, cudaMemcpyHostToDevice);
if(threadnum < THREADperBLOCK)
{
XXX_kernel<<<1, threadnum, 0>>>(ge, gr,gs,gxa, gya,gflag);
}else
{
XXX_kernel<<<(threadnum+THREADperBLOCK-1)/THREADperBLOCK,THREADperBLOCK, 0>>>(ge, gr,gs,gxa, gya,gflag);
}
cudaMemcpy( flag, gflag, sizeof(char)*THREAD, cudaMemcpyDeviceToHost);
if(!printerror(“after XXX_Ckernel”))
{
init=0;
return false;
}else
return true;

}

这样说吧……
1.你程序中的threadnum/THREADperBLOCK不一定跟warp的尺度对齐(即32的整数倍)
2.你程序中的(threadnum+THREADperBLOCK-1)/THREADperBLOCK也可能比你需要计算的threadnum多出来一块。
3.感觉你调用部分写成这样,可能threadnum也是随不同循环次数变化的。
综上,你是否在内核中考虑了1和2两点,对数据边界做了保护,我不得而知。而这可能是你程序最容易出现bug的地方。

[

问您一个问题: 当通过geterror得知当前gpu已经出错,怎么处理,需要将gpu卡重新初始化么,大概步骤是什么样的

正常情况,如果得知GPU之前的计算/传输等出现问题,说明程序出错,一般会终止程序。
如果你希望程序继续运行,并利用GPU资源,你只需用:
cudaDeviceSynchronize();/cudaDeiviceReset();
ierr=cudaGetLastError();
吃掉缓存的ierr信息,就可以继续使用了。

[

我的kernel最多起用8000个线程,在分配全局内存时我按照8000个线程进行分配。实际启动的线程是根据需求而定的,上层需要多少起用多少个线程就起用多少个线程。我的threadperblock是256。threadnum不是32的倍数,应该只有效率问题,不会有别的问题

我的顯示卡同時有接螢幕輸出也有做cuda計算

如果做一個長時間且需要很大量記憶體的計算時如果邊看影片或做其他事情

我發現記憶體在存取時會出錯,例如某些值會變成#nan或#inf

但是如果不做事情或把程式放到tesla卡上就不會算錯

這是我的經驗

您好,看到您描述的現象,如果您願意的話,不妨向本版常駐的NV原廠支持人員反映并重現下您遇到的問題,看看是不是驅動方面的BUG。照說如果申請不到足夠的空間,是不能執行的,而且申請來計算的空間也不會被其他程式改寫。

感謝您分享此經驗,并歡迎您進一步反饋此問題。

祝您好運~

好的!我過幾天再把之前的程式找出來跑看看,我有猜想可能是我本身的卡是超頻闆的關係

我先憑印象簡述一下我遇到的經過

每次跑cuda時我會記錄每個迴圈走一次的時間監測GPU的狀態順便做為程式改進的基準

有時候就會看到cuda跑的時間會比平常久,這時滑鼠隨便亂滑就有機會讓程式出錯

這時候就要開啟超頻程式把記憶體頻率降下來一些減少出錯可能*

*我的顯示卡預設頻率就是超頻的

另外,有時候我把已經在我的顯示卡測試過的程式移到tesla上運行時

跑出來的結果會變得很奇怪!!

只是程式有點龐大一時間無法找出是哪個環節出問題

當然也不排除是自己程式碼輸入錯誤

等我這星期考完期末考後再進一步分析原因這兩個問題

您好:感謝您的反饋。

一邊跑CUDA一邊跑其他應用,確實可能因為資源調度等使運行變慢。
以及超頻狀態下的顯存確實有出錯的可能。

不過具體原因還是期待您進一步的研究。

祝您好運~