为什么 Clang 分配 std::complex 这么快?
Why Clang allocate std::complex so fast?
我已经使用 GCC、Clang 和 Intel C++ 编译器测试了 std::complex<double>
数组的内存分配性能。我发现这些编译器之间存在显着的性能差异。 Clang 比其他编译器快几个数量级。
有谁能分析一下原因吗?非常感谢!下面附上测试代码、测试环境和测试结果详情。
附件
性能测试代码如下:
#include <iostream>
#include <complex>
#include <sys/time.h>
#include <stdlib.h>
double GetWallTime(void) {
struct timeval time;
if (gettimeofday(&time, NULL)) { return 0; }
return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
int main(int argc, char *argv[]) {
auto size = atol(argv[1]);
auto time_now = GetWallTime();
auto double_array = new double [size];
std::cout << "allocate double[" << size << "]: use "
<< GetWallTime() - time_now << " sec" << std::endl;
delete[] double_array;
time_now = GetWallTime();
auto c99cplx_array = new double _Complex [size];
std::cout << "allocate double _Complex[" << size << "]: use "
<< GetWallTime() - time_now << " sec" << std::endl;
delete[] c99cplx_array;
time_now = GetWallTime();
auto stdcplx_array = new std::complex<double> [size];
std::cout << "allocate std::complex<double>[" << size << "]: use "
<< GetWallTime() - time_now << " sec" << std::endl;
delete[] stdcplx_array;
return 0;
}
在一台 Linux Xeon E5-2680 v2 *2 CPU 和 64G DDR3 内存的机器上,我使用这三个编译器编译这段代码并 运行 测试。我得到以下结果:
将 g++
7.5.0 与 --std=c++11 -O3
标志一起使用:
allocate double[10000000]: use 5.6982e-05 sec
allocate double _Complex[10000000]: use 1.71661e-05 sec
allocate std::complex<double>[10000000]: use 0.0911679 sec
使用 icpc
19.1.0.166 和 --std=c++11 -O3
标志:
allocate double[10000000]: use 7.41482e-05 sec
allocate double _Complex[10000000]: use 1.69277e-05 sec
allocate std::complex<double>[10000000]: use 0.087034 sec
使用clang++
版本
> clang++ --version
Intel(R) oneAPI DPC++ Compiler 2021.1-beta03 (2019.10.0.1121)
Target: x86_64-unknown-linux-gnu
Thread model: posix
带有 --std=c++11 -O3
个标志:
allocate double[10000000]: use 4.19617e-05 sec
allocate double _Complex[10000000]: use 9.53674e-07 sec
allocate std::complex<double>[10000000]: use 1.19209e-06 sec
因为你的考试很糟糕。 Clang 完全删除了 new/delete 因为它毫无意义。您正在有效地对此进行分析:
#include <complex>
int main() {
auto ptr = new std::complex<double>[1000];
delete [] ptr;
return 0;
}
哪个 clang 正确地简化为:
main: # @main
xor eax, eax
ret
gcc 另一方面分配和释放内存。您不是在测试分配速度,而是在测试一个什么都没有的汉堡。不要像这样进行微基准测试,而是在 实际代码 上使用分析器。
如果你想分析这个,做:
volatile auto stdcplx_array = new std::complex<double> [size];
这将为每个编译器提供准确的基准测试(并不是说您的基准测试值得做 - 它只会减少为新的 + memset + 删除)。
我已经使用 GCC、Clang 和 Intel C++ 编译器测试了 std::complex<double>
数组的内存分配性能。我发现这些编译器之间存在显着的性能差异。 Clang 比其他编译器快几个数量级。
有谁能分析一下原因吗?非常感谢!下面附上测试代码、测试环境和测试结果详情。
附件
性能测试代码如下:
#include <iostream>
#include <complex>
#include <sys/time.h>
#include <stdlib.h>
double GetWallTime(void) {
struct timeval time;
if (gettimeofday(&time, NULL)) { return 0; }
return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
int main(int argc, char *argv[]) {
auto size = atol(argv[1]);
auto time_now = GetWallTime();
auto double_array = new double [size];
std::cout << "allocate double[" << size << "]: use "
<< GetWallTime() - time_now << " sec" << std::endl;
delete[] double_array;
time_now = GetWallTime();
auto c99cplx_array = new double _Complex [size];
std::cout << "allocate double _Complex[" << size << "]: use "
<< GetWallTime() - time_now << " sec" << std::endl;
delete[] c99cplx_array;
time_now = GetWallTime();
auto stdcplx_array = new std::complex<double> [size];
std::cout << "allocate std::complex<double>[" << size << "]: use "
<< GetWallTime() - time_now << " sec" << std::endl;
delete[] stdcplx_array;
return 0;
}
在一台 Linux Xeon E5-2680 v2 *2 CPU 和 64G DDR3 内存的机器上,我使用这三个编译器编译这段代码并 运行 测试。我得到以下结果:
将 g++
7.5.0 与 --std=c++11 -O3
标志一起使用:
allocate double[10000000]: use 5.6982e-05 sec
allocate double _Complex[10000000]: use 1.71661e-05 sec
allocate std::complex<double>[10000000]: use 0.0911679 sec
使用 icpc
19.1.0.166 和 --std=c++11 -O3
标志:
allocate double[10000000]: use 7.41482e-05 sec
allocate double _Complex[10000000]: use 1.69277e-05 sec
allocate std::complex<double>[10000000]: use 0.087034 sec
使用clang++
版本
> clang++ --version
Intel(R) oneAPI DPC++ Compiler 2021.1-beta03 (2019.10.0.1121)
Target: x86_64-unknown-linux-gnu
Thread model: posix
带有 --std=c++11 -O3
个标志:
allocate double[10000000]: use 4.19617e-05 sec
allocate double _Complex[10000000]: use 9.53674e-07 sec
allocate std::complex<double>[10000000]: use 1.19209e-06 sec
因为你的考试很糟糕。 Clang 完全删除了 new/delete 因为它毫无意义。您正在有效地对此进行分析:
#include <complex>
int main() {
auto ptr = new std::complex<double>[1000];
delete [] ptr;
return 0;
}
哪个 clang 正确地简化为:
main: # @main
xor eax, eax
ret
gcc 另一方面分配和释放内存。您不是在测试分配速度,而是在测试一个什么都没有的汉堡。不要像这样进行微基准测试,而是在 实际代码 上使用分析器。
如果你想分析这个,做:
volatile auto stdcplx_array = new std::complex<double> [size];
这将为每个编译器提供准确的基准测试(并不是说您的基准测试值得做 - 它只会减少为新的 + memset + 删除)。