use*_*016 13
指令预测意味着指令由线程有条件地执行,具体取决于谓词.谓词为true的线程执行指令,其余的则不执行任何操作.
例如:
var = 0;
// Not taken by all threads
if (condition) {
var = 1;
} else {
var = 2;
}
output = var;
Run Code Online (Sandbox Code Playgroud)
会导致(不是实际的编译器输出):
mov.s32 var, 0; // Executed by all threads.
setp pred, condition; // Executed by all threads, sets predicate.
@pred mov.s32 var, 1; // Executed only by threads where pred is true.
@!pred mov.s32 var, 2; // Executed only by threads where pred is false.
mov.s32 output, var; // Executed by all threads.
Run Code Online (Sandbox Code Playgroud)
总而言之,这是3条指令if,没有分支.效率很高.
带分支的等效代码如下所示:
mov.s32 var, 0; // Executed by all threads.
setp pred, condition; // Executed by all threads, sets predicate.
@!pred bra IF_FALSE; // Conditional branches are predicated instructions.
IF_TRUE: // Label for clarity, not actually used.
mov.s32 var, 1;
bra IF_END;
IF_FALSE:
mov.s32 var, 2;
IF_END:
mov.s32 output, var;
Run Code Online (Sandbox Code Playgroud)
注意它是多长时间(5条指令if).条件分支需要禁用部分warp,执行第一个路径,然后回滚到warp发散的点并执行第二个路径直到两个收敛.它需要更长的时间,需要额外的簿记,更多的代码加载(特别是在有许多指令要执行的情况下),因此需要更多的内存请求.所有这些都使得分支比简单的预测慢.
实际上,在这个非常简单的条件赋值的情况下,编译器可以做得更好,只有2条指令if:
mov.s32 var, 0; // Executed by all threads.
setp pred, condition; // Executed by all threads, sets predicate.
selp var, 1, 2, pred; // Sets var depending on predicate (true: 1, false: 2).
Run Code Online (Sandbox Code Playgroud)