我有三个问题要问
答案 0 :(得分:2)
1是否可以为单个块提供多个处理器,以便我的程序获得多处理器平台的一些好处
简单回答:不。
CUDA编程模型将一个线程块映射到一个多处理器(SM);该块不能跨两个或多个多处理器分割,一旦启动,它就不会从一个多处理器移动到另一个多处理器。
如您所见,CUDA提供__syncthreads()
以允许块内的线程进行同步。这是一个成本非常低的操作,部分原因是块内的所有线程都非常接近(在同一个SM上)。如果他们被允许分裂那么这将不再可能。另外,块内的线程可以通过共享共享存储器中的数据来协作;共享内存是SM的本地内存,因此拆分块也会破坏它。
2我可以同步不同块的线程吗?
不是真的没有。你可以做一些事情,比如让最后一个块做一些特别的事情(参见SDK中的threadFenceReduction示例),但一般同步是不可能的。当您启动网格时,您无法控制将块安排到多处理器上,因此任何尝试进行全局同步都可能会导致死锁。
3如何找出翘曲尺寸?它是针对特定硬件固定的吗?
是的,它是固定的。事实上,对于所有当前支持CUDA的设备(1.x和2.0),它固定为32.如果您依赖于warp大小,那么您应该通过检查warp大小来确保向前兼容性。
在设备代码中,您只需使用特殊变量warpSize
即可。在主机代码中,您可以使用以下命令查询特定设备的扭曲大小:
cudaError_t result;
int deviceID;
struct cudaDeviceProp prop;
result = cudaGetDevice(&deviceID);
if (result != cudaSuccess)
{
...
}
result = cudaGetDeviceProperties(&prop, deviceID);
if (result != cudaSuccess)
{
...
}
int warpSize = prop.warpSize;
答案 1 :(得分:0)
从cuda 2.3开始每个线程块一个处理器。在cuda 3 / Fermi处理器中可能有所不同,我不记得
不是真的,但......(根据您的要求,您可能会找到解决方法) 阅读这篇文章CUDA: synchronizing threads
答案 2 :(得分:0)
#3。您可以使用cuDeviceGetProperties - see doc
查询SIMDWidth答案 3 :(得分:0)
要跨多个块同步线程(至少就内存更新而言),您可以使用新的__threadfence_system()
调用,该调用仅适用于Fermi设备(Compute Capability 2.0及更高版本)。 CUDA编程指南(CUDA 3.0)中描述了此功能。
答案 4 :(得分:-1)
我可以通过以下方法同步不同块的线程。请告诉我这个approch是否有任何问题(我想会有一些但是因为我对cuda没有多少经验我可能没有考虑过一些事实)
__global__ void sync_func(int *glob_var){
int i = 0 ; //local variable to each thread
int total_threads = blockDim.x *threadDim.x
while(*glob_var != total_threads){
if(i == 0){
atomicAdd(int *glob_var, 1);
i = 1;
}
}
执行所有线程同时执行的代码; }