Re: [问题] CUDA新手上路 平行度及硬件相关问题

楼主: friends29 (凉哥哥)   2016-12-03 17:38:53
※ 引述《tmbyksdG (雨神妹妹的男朋友)》之铭言:
: 开发平台(Platform): (Ex: Win10, Linux, ...)
: Linux上安装CUDA环境 (CUDA版本为8.0 运算能力为3.7)(Tesla K80)
: 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
: NVCC
: 额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
: 问题(Question):
: 硬件方面:
: 1.我执行deviceQuery侦测到2个device(device0:Tesla K80, device1:K80),估狗发现K80
: 是由两个GK210核心所组成,那我侦测到的device是指有两个K80(4个GK210)的意思吗?
: 还是侦测到的两个device其实就是GK210?
: 2.13个SMX,总共有2496个cores,所以我一次可以同时做运算的数量是否为2496个threads?
: 软件方面:
: 我写了一个64 * 64的矩阵乘法,我想测试不同的block & thread数量去做运算,哪个执
: 行时间会比较短,我试了两种block的配置(thread数量刚好为4096,一个thread执行一
: 个输出矩阵的一个element)。
: (1)dim3 dimBlock(32, 32);
: dim3 dimGrid(2, 2);
: 这个配置是以下附的程式码配置,执行结果是正常的。
: (2)dim3 dimBlock(4, 128);
: dim3 dimGrid(1, 8);
: 换成这样配置编译之后,结果却只有大约三分之一是正常的值,其余却都是0
: ,我的threadIdx.x & threadIdx.y都是由0-1023,请问这是发生了什么错误吗?
: 另外,我想知道执行运算时thread做了什么事情,每个thread里面装的是什么东西呢,是
: 我输入的资料吗?还是加跟乘这两个指令呢?
: 喂入的资料(Input):
:
: ...
:
: 补充说明(Supplement):
: 请版上的各位先进指导一下我,谢谢。另外,手机排版请见谅。
原文的code恕删
小弟刚好也在玩cuda,所以来试试看是不是能帮助到原Po,版上高手如云,还请多指教。
硬件部分的问题恕在下驽顿...(被巴头,不过你说的显卡上总共有几个core,
同时就可以有几个执行绪在执行这件事情是对的,不过要看你的 Grid, Block 参数
怎么下,这个部分你必须先从你的显示卡的计算能力开始了解起,关键字:Warp。
如果参数下歪了,可能就会有一小段时间会有几个 core 在闲置,当然每台机器
最适合的参数都不一样,我自己也是还在摸索这个部分,这是我目前理解到的程度,
,如果有错误的地方还请高手指点。
再来软件方面我就熟悉多了,cuda真的是很困难debug,在下常常被indexing搞的
不要不要的。首先呢,你说你的 threadIdx.x, threadIdx.y 都是从 0 - 1023,这是
一个大问题,先假设你没有笔误,让我们来算算看,一个 Block 总共的 thread 数目
最多是 1024 (这个部分我不确定你的机器是否一样,所以你最好先了解一下),好
一般可以把一个 Block 想像成一个三维阵列的 thread,所以一个 Block 总共会有的
thread 数目是 x * y * z (x, y, z)各代表一个维度的执行绪总数,我们把你的
例子套进来,1024 * 1024 * 1,阿搭,这不是就爆了吗。所以你要确定你的 threadIdx
的 range到底是多少到多少。
再来你说你的输出有些值对,有些值不对,哈哈哈~哈威(再度被巴,这个问题
有好几种可能,第一,可能你从头到尾所有的 thread 只改到 output array 的其中
一部分,所以剩下的部份当然就是0啦,第二种可能,你某些的 Block access 了他
可以用的 memory 但是有些 Block 却没有(以为我又要唱歌了吗 威。这个状况下
除了你从 code 一行一行去检查之外,还有一个不错用的方式,不过我很好奇,既然
你都会用 cudaEvent_t 了,怎么不会用这个: cudaError_t,这位大大就是你找错
的好伙伴,实作部分如下:
cudaError_t status;
MyKernel<<< grd, blk >>>( ... ); // 你的名字(X 你的kernel(O
status = cudaGetLastError(); // 问问 cuda 大大我刚刚有没有做错什么
if( status != cudaSuccess ){ // 如果我有做错 请告诉我错在哪
cout << cudaGetErrorName( status ) << ":" << cudaGetErrorString( status );
// exit(255); // 看个人决定要不要继续执行啦
}
使用上大致就是这样,我个人是会省去 cudaGetErrorName() 的部份,因为我比较懒惰,
原Po可以自己去玩玩看,在决定要怎么使用,你有你自己的style。
这应该是第三个问题吧,想知道每个 thread 做了什么,建议妳自己玩玩看这个,
写一个 kernel 处理一个大小为 1024 的 array,然后只使用一个 Block 来玩,参数
就可以这样下 <<< 1, blk >>>, blk 可以是 1 - 1024 任何的数字。然后在里面让一
个 thread 只改一个 array element,array index 依据 threadIdx.x。这样你要他
做什么都可以,最后把它输出出来自己看看就知道啦。剧透一下每个 thread 其实都
会执行你 kernel 的内容,不同的地方只在于 threadIdx, blockIdx 这些变量的值会
不一样。
回答的有点简略,不过希望能够帮到你。
作者: sunneo (艾斯寇德)   2016-12-04 21:00:00
那只是在表示x,y,z个别的最大值,但仍得保持x*y*z<1024
作者: opl164 (opl)   2016-12-04 20:41:00
一个block内的thread最多是1024个 可是max dimension ofa thread block是(1024,1024,64) 为什么会这样?

Links booklink

Contact Us: admin [ a t ] ucptt.com