使用模数的不同值时的速度差异

时间:2013-01-24 22:40:57

标签: c++ c gcc

我正在使用gcc 4.6.3并创建大量随机短裤。我用以下语句生成它们:

val = SHRT_MAX; //as defined by limits.h
while(array<end) {
    *array++ = rand() % val;
}

这是一个相当快速的操作,即使对于大约5,000,000个元素的阵列几乎立即完成。我很好奇我的排序效率,数量变化较小,并改为:

val = 3;

这导致了相当大的速度差异,它比原始语句运行得慢得多。什么导致如此大的速度差异?

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 % 256x & 255相同。不幸的是,当价值可能是负数时,它就不那么容易了......