[问题] CUDA shared-memory

楼主: hardman1110 (笨小孩)   2017-10-03 10:12:05
开发平台(Platform): (Ex: Win10, Linux, ...)
WIN10
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
VC2017
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
CUDA 9.0
问题(Question):
想透过 shared memory 来加速kernal的效能
利用treadid 平行assign资料 也有用__syncthreads 来同步
但资料还是跟用循环跑的不一样 (结果有错)
想请问大大们我的使用方式有错吗? 还有vc上可以单步执行来看CUDA变量吗?
喂入的资料(Input):
一维阵列的输入与输出指标
预期的正确结果(Expected Output):
USE_SHARED_MEM = 0 与 = 1 data值要一样
错误结果(Wrong Output):
github:
https://github.com/ChiFang/question/blob/master/CUDA_SharedMem.cu
USE_SHARED_MEM = 1 会导致最后结果错误,表示data值不一样 (后面程式完全一模一样)
程式码(Code):(请善用置底文网页, 记得排版)
#define USE_SHARED_MEM 1
__global__ void kernal_test(const int a_RangeUpScale, const int
*a_CostData, int *a_Input)
{
// Get the work index of the current element to be processed
int y = blockIdx.x*blockDim.x + threadIdx.x; //执行绪在阵列中
对应的位置
#if USE_SHARED_MEM == 1
__shared__ int Buff[32];
#else
int Buff[32];
#endif
// Do the operation
for (int x = 1; (x < g_ImgWidth_CUDA); x++)
{
int TmpPos = y*Area + (x-1)*a_RangeUpScale;
#if USE_SHARED_MEM == 1
// Synchronize to make sure the sub-matrices are loaded before starting
the computation
__syncthreads();
if (threadIdx.x < 32)
{
Buff[threadIdx.x] = a_CostSmooth[TmpPos + threadIdx.x];
}
// Synchronize to make sure the sub-matrices are loaded before starting
the computation
__syncthreads();
#else
for (int cnt = 0; cnt < 32 ;cnt++)
{
Buff[cnt] = a_CostSmooth[TmpPos + cnt];
}
#endif
// use Buff to do something
}
}
补充说明(Supplement):
grid size = 8 block size = 135 所以thread id 一定会大于32
作者: johnjohnlin (嗯?)   2017-10-03 10:30:00
do something 里面通常还要有一个 syncthread
楼主: hardman1110 (笨小孩)   2017-10-03 10:40:00
原因是什? 前面的同步不算吗? 困惑中= =
作者: johnjohnlin (嗯?)   2017-10-03 10:44:00
你循环绕回去的时候会写到 shared memory
楼主: hardman1110 (笨小孩)   2017-10-03 11:27:00
Do something 之后就不会更改值了所以我才在一开始同步就算绕回去应该再同步一次不是吗?
作者: a1u1usul3 (Q-Max)   2017-10-03 12:16:00
do something的时候有的thread提早做完先去改值了,有的thread还没做完需要用旧的值,但被改了
楼主: hardman1110 (笨小孩)   2017-10-03 12:37:00
所以我只要在使用前一刻同步就好囉?还有在assign值前同步已尝试在assign前后都同步,但结果还是会错(晕
作者: johnjohnlin (嗯?)   2017-10-03 14:00:00
那 do something 里面是不是有 break 之类的BTW, blockDim.x = 135 是个很糟糕的选择,尽量避免
作者: a1u1usul3 (Q-Max)   2017-10-03 14:09:00
code还是贴在codepad吧然后你的code会不会逻辑上就错了不用sharedMeomry的时候,每个thread从自己的TmpPos拿32个元素进private memory,而TmpPos每个thread都不同结果用SharedMemory的时候32人从自己的TmpPos拿一个元素进SharedMemory
楼主: hardman1110 (笨小孩)   2017-10-03 14:24:00
a1大 已补上github好读版连结我这边纯粹想让多个thread 同时assign值 甭跑回圈
作者: a1u1usul3 (Q-Max)   2017-10-03 14:27:00
SharedMemory的功能是让多个thread共用的资料不用重复你资料的并没有共用不是吗@@?
楼主: hardman1110 (笨小孩)   2017-10-03 14:28:00
我想通了~抱歉 确实把y当执行绪切 每个thread y不同纯共用的话 感觉用register 就好 阵列大小不大
作者: a1u1usul3 (Q-Max)   2017-10-03 14:31:00
thread内共用->register threads间共用->sharedMemoryBlocks间共用->GlobalMemory好像还有很潮的shuffle,threads间共用的样子
楼主: hardman1110 (笨小孩)   2017-10-03 14:55:00
要在加速的话 好像还可以用surface memory来读写?感谢各位大大指点

Links booklink

Contact Us: admin [ a t ] ucptt.com