gpt4 book ai didi

由于 if 语句导致 C++ 大量性能损失

转载 作者:IT老高 更新时间:2023-10-28 23:03:22 31 4
gpt4 key购买 nike

我在 4 个线程中运行 while 循环,在循环中我正在评估函数并递增计数器。

while(1) {
int fitness = EnergyFunction::evaluate(sequence);

mutex.lock();
counter++;
mutex.unlock();
}

当我运行这个循环时,正如我在 4 个运行线程中所说的那样,我每秒得到大约 20 000 000 次评估。

while(1) {
if (dist(mt) == 0) {
sequence[distDim(mt)] = -1;
} else {
sequence[distDim(mt)] = 1;
}
int fitness = EnergyFunction::evaluate(sequence);

mainMTX.lock();
overallGeneration++;
mainMTX.unlock();
}

如果我为序列添加一些随机突变,我每秒会得到大约 13 000 000 次评估。

while(1) {
if (dist(mt) == 0) {
sequence[distDim(mt)] = -1;
} else {
sequence[distDim(mt)] = 1;
}
int fitness = EnergyFunction::evaluate(sequence);

mainMTX.lock();
if(fitness < overallFitness)
overallFitness = fitness;

overallGeneration++;
mainMTX.unlock();
}

但是当我添加简单的 if 语句来检查时,如果新的适应度小于旧的适应度,如果是这样,那么用新的适应度替换旧的适应度。

但是性能损失是巨大的!现在我每秒得到约 20 000 次评估。如果我删除随机突变部分,我还会每秒获得约 20 000 次评估。

变量的overallFitness被声明为

extern int overallFitness; 

我很难弄清楚造成如此大的性能损失的问题是什么。比较两个 int 是否需要这样的时间操作?

我也不认为这与互斥锁有关。

更新

这种性能损失不是因为分支预测,而是编译器只是忽略了这个调用 int fitness = EnergyFunction::evaluate(sequence); .

现在我添加了 volatile并且编译器不再忽略该调用。

也感谢您指出分支预测错误和atomic<int> ,不知道他们!

因为 atomic 我也去掉了 mutex 部分,所以最终的代码是这样的:

while(1) {
sequence[distDim(mt)] = lookup_Table[dist(mt)];
fitness = EnergyFunction::evaluate(sequence);
if(fitness < overallFitness)
overallFitness = fitness;
++overallGeneration;
}

现在我每秒获得约 25 000 次评估。

最佳答案

您需要运行探查器才能了解这一点。在 Linux 上,使用 perf

我的猜测是 EnergyFunction::evaluate() 正在被完全优化掉,因为在第一个示例中,您没有使用结果。所以编译器可以丢弃整个事情。您可以尝试将返回值写入 volatile 变量,这将强制编译器或链接器不优化调用。 1000 倍的加速绝对不是简单的比较。

关于由于 if 语句导致 C++ 大量性能损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33415219/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com