考虑以下伪代码:
x1 = DEFAULT_VAL_1;
y1 = DEFAULT_VAL_2;
for (i = 0; i < CONST1; i++) {
x0 = *x0buffer++;
y0 = *y0buffer++;
if (x0*y1 > y0*x1)
{
x1 = x0;
y1 = y0;
pos = i;
}
}
感兴趣的输出x1
,y1
和pos
,
你能推荐一种方法来优化它,以避免if
语句吗?
答案 0 :(得分:1)
如果您使用的是x86,那么您不相信您的编译器会对此进行优化,而您愿意进行汇编,这样就可以解决问题:
x1 = DEFAULT_VAL_1;
y1 = DEFAULT_VAL_2;
for (i = 0; i < CONST1; i++) {
x0 = *x0buffer++;
y0 = *y0buffer++;
asm (
"cmp %3, %4\n\t"
"cmovl %5, %0\n\t"
"cmovl %6, %1\n\t"
"cmovl %7, %2\n\t"
: "+g" (pos)
, "+g" (x1)
, "+g" (y1)
: "r" (x0*y1)
, "r" (y0*x1)
, "r" (i)
, "r" (x0)
, "r" (y0)
: "cc"
);
}
答案 1 :(得分:1)
你可以试试这个版本
for (i = 0; i < CONST1; i++) {
x0 = *x0buffer++;
y0 = *y0buffer++;
c = (x0*y1 > y0*x1);
x1 = x0 *c + x1 * (c^1);
y1 = y0 *c + y1 * (c^1);
pos = i* c + pos * (c^1);
}
看起来代码的计算密集程度要高得多,但在并行架构上,这将比原始版本执行得更快。
希望有所帮助
答案 2 :(得分:0)
假设您的字节长度为8位(根据需要进行修改)并且您的整数在MSB中有符号,那么这可能会更快或更快:
#define masked_replace(mask, a, b) a += ( (b) - (a) ) & (mask)
int mask = y0*x1 - x0*y1; // signed(!!!) int
mask >>= sizeof(mask) * 8 - 1;
masked_replace(mask, x1, x0);
masked_replace(mask, y1, y0);
masked_replace(mask, pos, i);