VS 2017 & 2019 运行 c++ 真的很慢
Posted
技术标签:
【中文标题】VS 2017 & 2019 运行 c++ 真的很慢【英文标题】:VS 2017 & 2019 run c++ really slow 【发布时间】:2020-01-12 12:47:29 【问题描述】:我开始使用 python 中的一个小程序,但运行它需要很长时间,所以我切换到 c++。我之前没有使用这种特定语言的经验(虽然在 c# 中编写了很多代码)并且开始使用网络编辑器:https://www.onlinegdb.com/online_c++_compiler。
我的 C++ 代码是:
clock_t start, end;
/* Recording the starting clock tick.*/
start = clock();
int R = 0;
int x = 0;
for (R = 6; R <= 10000; R = R + 2)
int X_min = ceil(0.5 * sqrt(2) * R);
int N_pairs = 0;
for (x = X_min; x < R; x++)
float y = sqrt(pow(R, 2) - pow(x, 2));
if (rint(y) == y)
N_pairs = N_pairs + 1;
if (N_pairs >= 4)
//cout << R << ", " << N_pairs;
//cout << "\n";
end = clock();
//Calculating total time taken by the program.
double time_taken = double(end - start) / double(CLOCKS_PER_SEC);
cout << "Time taken by program is : " << time_taken;
cout << " sec " << endl;
//cout << "1" << "|" << "2" << "|" << "3 \n";
//cout << "4" << "|" << "5" << "|" << "6 \n";
//cout << "7" << "|" << "8" << "|" << "9 \n";
一切运行良好,但是 Web 编辑器似乎有一个内置的最大时间边界,所以此时我决定将它交给 Visual Studio。
我复制粘贴代码并运行它:
网络编辑器用了 0.272273 秒完成代码 Visual Studio 用了 2.446 秒来运行它。我尝试将 VS 从 2017 版更新到 2019 版,但没有效果。
为什么 VS 运行代码需要这么长时间?我该如何解决?
【问题讨论】:
您是否启用了发布构建配置? 正如@walnut 所说。使用不同的优化/构建标志运行可以发挥巨大的作用。请参阅:godbolt.org/z/jpgVYx,其中一个使用优化级别 3,另一个使用 0。对我来说,这是 30 倍的时间差异。 (虽然编译器与 msvc 不同) 我确实启用了发布构建配置。没有它需要更长的时间:8.701 秒 您不能在 Windows 上使用clock
来比较性能。
使用sqrt(R*R - x*x)
来避免pow(),一定要针对x64。
【参考方案1】:
主要问题是VC++没有内联rint(float)
调用:
movaps xmm0, xmm6
call rint
ucomisd xmm0, xmm6
link to godbolt
您可以通过将rint(y)
替换为“手动”舍入来获得良好的加速效果:
改变
if (rint(y) == y)
到
if (int(y+0.5) == y)
在我的机器上从 0.8 s 下降到 0.04 s(使用 /O2 /fp:fast
编译)
您还需要在循环外使用 N_pairs
,否则(好的)编译器可以优化所有内容。
【讨论】:
【参考方案2】:优化的第一条规则:错误程序的性能无关紧要。
看来您正在寻找x^2 + y^2 = R^2
的整数解。但是,使用float
数据类型进行中间存储会产生很多误报。将N_pairs
移出循环(以防止完全删除该循环,正如@rustyx 已经指出的,并计算所有对)导致7886 对;与double
:5681。
最后一个数字也对应于完全整数检查,这要快得多(在我的系统上为 21 毫秒)。这是我的代码:
#include <iostream>
#include <chrono>
int main()
auto t = std::chrono::high_resolution_clock::now();
int N_pairs = 0;
double d = 0.5 * sqrt(2);
for (int R = 6; R <= 10000; R = R + 2)
int X_min = ceil(d * R);
for (int x = X_min; x < R; x++)
int y = sqrtf(R * R - x * x);
if(x*x + y*y == R*R)
N_pairs = N_pairs + 1;
std::cout << "Time taken by program is: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - t).count()
<< " ms" << std::endl;
std::cout << "N_pairs: " << N_pairs << std::endl; // with float: 7886; with double or int: 5681
return 0;
【讨论】:
感谢您的回复。我在循环中有 N_pairs 的原因是因为我对每个“R”的对数感兴趣,而不是对所有 R 的总对数感兴趣。也许我应该每次都将它设置为零,而不是一遍又一遍地声明它,但我还没有检查过。这是我第一次不得不优化程序。此外,您将变量 y 声明为整数这一事实是否会引入误报,因为您立即对 sqrt 进行舍入?我尝试将其更改为加倍,虽然它不会影响 R 高达 10.000 的结果,但它对 R 高达 100.000 的结果有影响 @user11454816 - 我的代码不能有误报,因为要查看平方和是否等于 R 平方的整数测试。由于您提到的四舍五入,它可能有误报;我会通过检查y+1
-squared 是否有效来解决这个问题。以上是关于VS 2017 & 2019 运行 c++ 真的很慢的主要内容,如果未能解决你的问题,请参考以下文章