C++ 使用不同的模值时的速度差

C++ 使用不同的模值时的速度差,c++,c,gcc,C++,C,Gcc,我正在使用GCC4.6.3并创建一个大的随机短裤数组。我用以下语句生成它们: val = SHRT_MAX; //as defined by limits.h while(array<end) { *array++ = rand() % val; } 这造成了相当大的速度差异,运行速度比原始语句慢得多。是什么导致了如此大的速度差异?编译器可以优化模(a%B)的计算,其中B是一个常数。它用更简单的算术运算代替了实际的模运算。有关详细信息,请参见以下主题。但是,对于某些值的B,这样的

我正在使用GCC4.6.3并创建一个大的随机短裤数组。我用以下语句生成它们:

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

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

编译器可以优化模(a%B)的计算,其中B是一个常数。它用更简单的算术运算代替了实际的模运算。有关详细信息,请参见以下主题。但是,对于某些值的B,这样的优化比其他值更快


即使是CPU除法/模指令也可以完成不同的周期数(至少在某些CPU上)。请参见此处x86的数字:。

编译器可以优化模(a%B)的计算,其中B是常数。它用更简单的算术运算代替了实际的模运算。有关详细信息,请参见以下主题。但是,对于某些值的B,这样的优化比其他值更快


即使是CPU除法/模指令也可以完成不同的周期数(至少在某些CPU上)。请参见此处x86的数字:。

SHRT\u MAX
很可能大于或等于
RAND\u MAX
。声明:

*array++ = rand() % val;
可以优化为:

int rand_value= rand();
if (rand_value==RAND_MAX) rand_value= 0;
*array++= rand_value;
这会更快,因为它会用分支替换模数。第二个版本,其中
val
为3,无法优化为没有模数的更简单版本


%SHRT\u MAX
不能简化为按位操作。但结合如何指定
rand()
的知识,编译器肯定可以优化处理
rand()
的语句,并且大于或等于
rand\u MAX
SHRT\u MAX
的值很可能大于或等于
rand\u MAX
。声明:

*array++ = rand() % val;
可以优化为:

int rand_value= rand();
if (rand_value==RAND_MAX) rand_value= 0;
*array++= rand_value;
这会更快,因为它会用分支替换模数。第二个版本,其中
val
为3,无法优化为没有模数的更简单版本


%SHRT\u MAX
不能简化为按位操作。但结合如何指定
rand()。除以3要困难得多,因此编译器可能会决定除以3(或者执行比
2^n-1
变量慢的其他神奇操作)


您可以使用的最快模用于
2^n
,对于正值,它可以用一个单独的指令代替:
x%256
x&255
相同。不幸的是,当值可能为负值时,就不那么容易了…

SHRT\u MAX是一个
2^n-1
值,可以针对divide.Div进行优化用3除法要困难得多,因此编译器可能会决定用3除法(或者执行比
2^n-1
变量慢的其他神奇操作)


您可以使用的最快的模用于
2^n
,它可以用一个单独的指令代替,用于正值:
x%256
x&255
相同。不幸的是,当值可能为负值时,就不那么容易了…

两个字:编译器优化。某些模比其他模更容易修改。Just请注意,取均匀分布随机数的模并不一定会产生一定范围内的均匀分布随机数。@honk-您能详细说明一下吗(或链接到解释)?我不明白为什么会是这样。@GordonBailey:这几乎是一个关于随机数的常见问题解答。有关详细解释,请参阅。这里有一个答案。两个词:编译器优化。某些模比其他模更容易修改。正如一句话所说,取均匀分布随机数的模并不一定是正确的在一定范围内产生均匀分布的随机数。@honk-你能扩展一下吗(或链接到一个解释)?我不明白为什么会这样。@GordonBailey:这几乎是一个关于随机数的常见问题解答。有关详细解释,请参阅。这里是答案。3也是
2^n-1
n
=2).3也是
2^n-1
n
=2)。