我阅读here(第14页),提高ARM设备代码效率的一种方法是使用ARM_compiler特定关键字,如__promise
,并提到以下示例代码:
void f(int *x, int n)
{
int i;
__promise((n > 0) && ((n & 7) == 0)); /* My Question: How this line improves efficiency */
for(i = 0; i < n; i++)
{
x[i]++;
}
}
但我不会动摇这些额外的信息(循环指数是正的,可以除以8)可以提高效率!
有人可以解释一下吗?
答案 0 :(得分:2)
__promise((n > 0) && ((n & 7) == 0));
7
的二进制表示形式为0b111
。这告诉您n
的最后3位将始终为零。因此n
必须是8
的倍数。 Furtermore n
也将大于0
。
因此,您承诺编译器可以安全地将您的循环展开为8
的块,并且它至少会执行一次迭代。
编译器可以因此选择将代码重写为:
int i = 0;
do
{
x[i+0]++;
x[i+1]++;
x[i+2]++;
x[i+3]++;
x[i+4]++;
x[i+5]++;
x[i+6]++;
x[i+7]++;
} while ((i+=8) != n);
这将跳过一堆比较。
NEON VADD
指令甚至可以让您进一步优化:vaddq_s32
允许您将向量(1,1,1,1)添加到数组的四个元素组中一旦。因此,您的编译器可以用两个vadd指令替换该块(如果它感觉您可以从中受益)。