我从CUDA Profiler那里获得了信息.我很困惑为什么重播指令!= Grobal内存重播+本地内存重放+共享银行冲突重播?
请参阅我从profiler获得的以下信息:
Replayed Instructions(%): 81.60
Global memory replay(%): 21.80
Local memory replays(%): 0.00
Shared bank conflict replay(%): 0.00
Run Code Online (Sandbox Code Playgroud)
你能帮我解释一下吗?还有其他案例导致重播指令吗?
我读过 GPU 上的比较和分支很慢。我想知道多少钱。(我对 OpenCL 比较熟悉,但这个问题对于 CUDA、AMP 来说也很普遍……)
在我开始将代码移植到 GPU 之前,我想知道它。特别是我有兴趣在二维数组中的每个点的邻域(4 或 9 个最近邻)中找到最小值。即类似于卷积的东西,但我需要比较和分支而不是求和和相乘。
例如这样的代码(注意:此示例代码尚未针对 GPU进行优化以使其更具可读性......因此分区到工作组,预取本地内存......丢失)
for(int i=1;i<n-1;i++){ for(int j=1;j<n-1;j++){ // iterate over 2D array
float hij = h[i][j];
int imin = 0,jmin = 0;
float dh,dhmin=0;
// find lowest neighboring element h[i+imin][j+jmin] of h[i][j]
dh = h[i-1][j ]-hij; if( dh<dhmin ){ imin = -1; jmin = 0; dhmin = dh; }
dh = h[i+1][j ]-hij; if( dh<dhmin ){ imin = +1; jmin …Run Code Online (Sandbox Code Playgroud) 假设由单个warp(为简单起见)执行的CUDA内核到达if- else语句,其中warp中的condition20个线程满足,32 - 20 = 12个线程不:
if (condition){
statement1; // executed by 20 threads
else{
statement2; // executed by 12 threads
}
Run Code Online (Sandbox Code Playgroud)
根据CUDA C编程指南:
如果warp的线程经由数据相关的条件分支发散,则warp一次执行一条公共指令,warp串行执行所采用的每个分支路径,禁用不在该路径上的线程,以及所有路径完成后,线程会聚回同一个执行路径.
因此,这两个语句将在不同的循环中顺序执行.
Kepler体系结构每个warp调度程序包含2个指令调度单元,因此能够在每个周期发出每个warp 2个独立指令.
我的问题是:在这个只有两个分支的设置中,为什么能够statement1和statement2不能由两个指令调度单元发出由warp中的32个线程同时执行,即20个线程执行statement1而另外12 个线程同时执行statement2?如果指令调度程序不是warp一次执行单个公共指令的原因,那么是什么?它是仅提供32线程宽指令的指令集吗?还是硬件相关的原因?
我正在尝试找到避免CUDA 内核中线程发散(分支或扭曲发散)的方法。
例如,我有以下条件赋值(a和b是char值,x和y是unsigned int值):
if (a == b) { ++x; }
else { ++y; }
Run Code Online (Sandbox Code Playgroud)
或者,或者:
if (a == b) { ++x; }
if (a != b) { ++y; }
Run Code Online (Sandbox Code Playgroud)
如何重写上述操作以避免分支?
我查看了类型转换内在函数,但没有从boolto转换可用int。我在想可能有一些技巧可以使用min,max和绝对值(例如,__sad)来获得适当的整数结果来为每种情况添加(即,1,0或0,1)。
似乎没有常规的int绝对值函数,但我看到的是:
计算| X ?是 | + …