gpt4 book ai didi

c++ - 使用 uniform_real_distribution 时 clang 性能下降

转载 作者:搜寻专家 更新时间:2023-10-31 02:01:53 24 4
gpt4 key购买 nike

以下代码在使用 uniform_real_distribution 时导致 g++ 和 clang++ 的时间非常不同。

#include <iostream>
#include <sstream>
#include <fstream>

#include <chrono>
#include <random>


std::mt19937::result_type seed = 0;
std::mt19937 gen(seed);
// std::uniform_int_distribution<size_t> distr(0, 1);
std::uniform_real_distribution<double> distr(0.0,1.0);

int main()
{
auto t_start = std::chrono::steady_clock::now();
for (auto i = 1; i <= 1000000; ++i)
{
distr(gen);
}
auto t_end = std::chrono::steady_clock::now();
std::cout << "elapsed time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(t_end - t_start).count() << " ns\n" << std::endl;

return 0;
}

使用以下命令编译:

clang++ -std=c++17 -O3 -flto -march=native -mllvm -inline-threshold=10000000 rng.cpp -o rng
g++ -std=c++17 -O3 -march=native rng.cpp -o rng

这会导致以下时间:

clang:  272929774 ns

gcc: 12054635 ns

当使用注释分布时,时间是:

clang:  48155862 ns

gcc: 50226810 ns

我在这里发现了一个相当古老的问题,它处理的是同样的问题,但是没有一个建议的解决方案适用于我的情况。

Clang performance drop for specific C++ random number generation

有人知道这里发生了什么吗?

最佳答案

看看 godbolt

在 gcc 编译器上被破坏 distr(gen); !!!

.L27:
dec esi
je .L25

这是一个什么都不做的for循环!

On clang 编译器不够智能:

.LBB0_1:                                # =>This Inner Loop Header: Depth=1
mov edi, offset gen
call double std::generate_canonical<double, 53ul, std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul> >(std::mersenne_twister_engine<unsigned long, 32ul, 624ul, 397ul, 31ul, 2567483615ul, 11ul, 4294967295ul, 7ul, 2636928640ul, 15ul, 4022730752ul, 18ul, 1812433253ul>&)
dec ebx
jne .LBB0_1

generate_canonical实际上被调用了。

基本上你必须使用 distr(gen); 的结果用它做一些会对代码结果产生影响的事情,否则编译器可以删除该代码。


simplest way to fix i t 是累积 distr(gen); 的结果并打印出来。

现在当你查看汇编时,你可以看到 clang正在调用函数 std::generate_canonical<double, 53ul, std::mersenne_twister_engine< .... >>gcc只是将相应的代码内联。

很可能这种差异是由标准库的不同组织引起的。 Clang 使用内置于标准库中的版本,而头文件中的 gcc 模板用于在刚刚创建的程序集中生成代码。当编译器从库中访问外部代码时,它无法确定它到底做了什么,因此它无法优化掉该代码(因为一些副作用可能隐藏在库中)。

关于c++ - 使用 uniform_real_distribution 时 clang 性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58283420/

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