gpt4 book ai didi

gcc - std::complex 乘法非常慢

转载 作者:行者123 更新时间:2023-12-03 15:52:07 25 4
gpt4 key购买 nike

我注意到使用重载的 std::complex 运算符将两个 * 值相乘比写出操作要慢得多。我看到了 50 倍的差异。这完全是荒谬的。我知道运算符(operator)需要检查输入中的 NaN,因为无穷大的定义是多么复杂。这真的可以解释 50 倍的时差吗?

我正在使用带有 -O3 -mavx -mavx2 -msse2 -mfma -mbmi 标志的 GCC 5.4.0。

这是测试代码:

#include <iostream>
#include <complex>
#include <chrono>
#include <vector>

int main( void ) {
size_t N = 10000;
std::vector< std::complex< double >> inbuf( N );
for( size_t k = 0; k < N; ++k ) {
inbuf[ k ] = std::complex< double >( std::rand(), std::rand() ) / ( double )RAND_MAX - 0.5;
}

std::complex< double > c2 = { 0, 0 };
auto t0 = std::chrono::steady_clock::now();
for( size_t i = 0; i < 10000; ++i ) {
for( size_t j = 0; j < N - 1; ++j ) {
double re = inbuf[ j ].real() * inbuf[ j + 1 ].real() - inbuf[ j ].imag() * inbuf[ j + 1 ].imag();
double im = inbuf[ j ].real() * inbuf[ j + 1 ].imag() + inbuf[ j ].imag() * inbuf[ j + 1 ].real();
c2.real( c2.real() + re );
c2.imag( c2.imag() + im );
}
}
auto t1 = std::chrono::steady_clock::now();
double time = ( std::chrono::duration< float >( t1 - t0 ) ).count();
std::cout << c2 << " using manual *: " << time << std::endl;

c2 = { 0, 0 };
t0 = std::chrono::steady_clock::now();
for( size_t i = 0; i < 10000; ++i ) {
for( size_t j = 0; j < N - 1; ++j ) {
c2 += inbuf[ j ] * inbuf[ j + 1 ];
}
}
t1 = std::chrono::steady_clock::now();
time = ( std::chrono::duration< float >( t1 - t0 ) ).count();
std::cout << c2 << " using stdlib *: " << time << std::endl;
return 0;
}

这是输出:
(-2.45689e+07,-134386) using manual *: 0.109344
(-2.45689e+07,-134386) using stdlib *: 5.4286

编辑:鉴于人们在评论中的不同结果,我对各种编译选项进行了更多测试。结果是 -mfma-mavx 开关导致“stdlib”版本如此之慢。 -mfma 开关为“手动”版本提供了约 25% 的性能提升,但将“stdlib”版本的速度降低了大约 13 倍:
cris@carrier:~/tmp/tests> g++ complex_test.cpp -o complex_test -O3 -std=c++11
cris@carrier:~/tmp/tests> ./complex_test
(-2.45689e+07,-134386) using manual *:0.138276
(-2.45689e+07,-134386) using stdlib *:0.412056
cris@carrier:~/tmp/tests> g++ complex_test.cpp -o complex_test -O3 -mfma -std=c++11
cris@carrier:~/tmp/tests> ./complex_test
(-2.45689e+07,-134386) using manual *:0.106551
(-2.45689e+07,-134386) using stdlib *:5.37662

我也尝试了 clang-800 (Mac OS) 并没有看到这种极端的减速。 Mac 上的 g++-5 与 Linux 上的 g++-5 相同。也许我发现了一个编译器错误?

最佳答案

我遇到了同样的问题,Visual C++ 中复杂计算的性能显然很慢。就我而言,事实证明,我在 Visual C++ 的 Debug模式下进行了时间测量。切换到 Release模式后,与双重计算相比,时间是合理的(考虑到复杂的操作包括多次双重计算)。

关于gcc - std::complex 乘法非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42659668/

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