我正在使用gcc 4.6.3并创建大量随机短裤。我用以下语句生成它们:
val = SHRT_MAX; //as defined by limits.h
while(array<end) {
*array++ = rand() % val;
}
这是一个相当快速的操作,即使对于大约5,000,000个元素的阵列几乎立即完成。我很好奇我的排序效率,数量变化较小,并改为:
val = 3;
这导致了相当大的速度差异,它比原始语句运行得慢得多。什么导致如此大的速度差异?
答案 0 :(得分:3)
SHRT_MAX
很可能大于或等于RAND_MAX
。声明:
*array++ = rand() % val;
可以优化为:
int rand_value= rand();
if (rand_value==RAND_MAX) rand_value= 0;
*array++= rand_value;
更快,因为它用分支替换模数。 val
为3的第二个版本无法优化为不带模数的简单版本。
% SHRT_MAX
无法简化为按位运算。但结合了如何指定rand()
的知识,编译器当然可以优化处理rand()
的语句和大于或等于RAND_MAX
的值。
答案 1 :(得分:2)
编译器可以优化模数(a%B)的计算,其中B是常数。它用更简单的算术运算取代了实际的模数。详细信息在Most optimized way to calculate modulus in C等主题中进行了解释。然而,对于某些B值而言,这种优化比其他值更快。
即使CPU分区/模数指令也可以完成不同的循环次数(至少在某些CPU上)。请在此处查看x86的数字:http://gmplib.org/~tege/x86-timing.pdf。
答案 2 :(得分:0)
SHRT_MAX是2^n-1
值,可以针对除法进行优化。除以3会更加困难,因此编译器可能会决定除以3(或执行一些比2^n-1
变量慢的其他魔术操作。
您可以使用的最快模数是2^n
,可以替换为单个和 - 指示,正值:x % 256
与x & 255
相同。不幸的是,当价值可能是负数时,它就不那么容易了......