我是否应该将两个类似的内核统一为“如果”语句,从而冒着性能损失的风险?

[英]Should I unify two similar kernels with an 'if' statement, risking performance loss?


I have 2 very similar kernel functions, in the sense that the code is nearly the same, but with a slight difference. Currently I have 2 options:

我有两个非常相似的内核函数,在某种意义上说,代码几乎相同,但有一点不同。目前我有两个选择:

  • Write 2 different methods (but very similar ones)
  • 写两种不同的方法(但是非常相似)
  • Write a single kernel and put the code blocks that differ in an if/else statement
  • 编写一个内核并将不同的代码块放在if/else语句中

How much will an if statement affect my algorithm performance?
I know that there is no branching, since all threads in all blocks will enter either the if, or the else.
So will a single if statement decrease my performance if the kernel function is called a lot of times?

if语句会对算法性能产生多大影响?我知道没有分支,因为所有块中的所有线程都将输入if或else。如果内核函数被多次调用,那么一个if语句是否会降低我的性能呢?

2 个解决方案

#1


92  

You have a third alternative, which is to use C++ templating and make the variable which is used in the if/switch statement a template parameter. Instantiate each version of the kernel you need, and then you have multiple kernels doing different things with no branch divergence or conditional evaluation to worry about, because the compiler will optimize away the dead code and the branching with it.

您还有第三种选择,即使用c++模板,并将if/switch语句中使用的变量作为模板参数。实例化所需内核的每个版本,然后有多个内核执行不同的操作,不需要担心分支发散或条件求值,因为编译器会优化死代码和分支。

Perhaps something like this:

也许是这样的:

template<int action>
__global__ void kernel()
{
    switch(action) {
       case 1:
       // First code
       break;

       case 2:
       // Second code
       break;
    }
}

template void kernel<1>();
template void kernel<2>();

#2


4  

It will slightly decrease your performance, especially if it's in an inner loop, since you're wasting an instruction issue slot every so often, but it's not nearly as much as if a warp were divergent.

它会稍微降低性能,尤其是在内部循环中,因为您经常会浪费一个指令问题槽,但这远不如翘曲是发散的。

If it's a big deal, it may be worth moving the condition outside the loop, however. If the warp is truly divergent, though, think about how to remove the branching: e.g., instead of

但是,如果这是一件大事,那么将条件移出循环可能是值得的。如果扭曲真的是发散的,那么考虑一下如何去除分支:例如,而不是

if (i>0) {
    x = 3;
} else {
    x = y;
}

try

试一试

x = ((i>0)*3) | ((i<3)*y);
智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2011/05/30/33c066e5a06bdd0b52afcb97399eb52e.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告