【发布时间】:2010-07-30 07:38:53
【问题描述】:
我需要快速否定大量的双打。如果 bit_generator 生成 0,则必须更改符号。如果 bit_generator 生成 1,则什么也不会发生。循环运行多次,bit_generator 非常快。在我的平台上,案例 2 明显快于案例 1。看起来我的 CPU 不喜欢分支。有没有更快、更便携的方法呢?对于案例 3,你怎么看?
// generates 0 and 1
int bit_generator();
// big vector (C++)
vector<double> v;
// case 1
for (size_t i=0; i<v.size(); ++i)
if (bit_generator()==0)
v[i] = -v[i];
// case 2
const int sign[] = {-1, 1};
for (size_t i=0; i<v.size(); ++i)
v[i] *= sign[bit_generator()];
// case 3
const double sign[] = {-1, 1};
for (size_t i=0; i<v.size(); ++i)
v[i] *= sign[bit_generator()];
// case 4 uses C-array
double a[N];
double number_generator(); // generates doubles
double z[2]; // used as buffer
for (size_t i=0; i<N; ++i) {
z[0] = number_generator();
z[1] = -z[0];
a[i] = z[bit_generator()];
}
编辑:添加了 case 4 和 C-tag,因为向量可以是一个普通数组。因为我可以控制如何生成双精度数,所以我重新设计了代码,如案例 4 所示。它同时避免了额外的乘法和分支。我认为它在所有平台上都应该很快。
【问题讨论】:
-
您可能使用迭代器而不是索引获得更好的性能(但可能不会,分析它)
-
非常依赖于平台。你能指定你的吗?
-
C中没有
vector<double>这样的东西。为什么这个问题有C标签? -
@Fred:因为他可以很容易地使用双精度数组,而且答案不会改变。
-
对不起 C 标签。 v 可以是一个普通数组。
标签: c++ c optimization floating-point