调试和发布版本中的执行时间很奇怪
Strange execution time in Debug and Release versions
我在VS2010中开始使用并行模式库,应用程序给了我预期的结果,但当我对调试版本和发布版本进行基准测试时,我在发布版本中得到了奇怪的执行时间,如下所示调试版本:"连续持续时间:1014"并行持续时间:437"发布版本"连续持续时间:31"并行持续时间:484"
这是我的应用程序代码
double DoWork(int workload)
{
double result=0;
for(int i =0 ; i < workload;i++)
{
result +=sqrt((double)i * 4*3) + i* i;
}
return result;
}
vector<double> Seqential()
{
vector<double> results(100);
for(int i = 0 ; i <100 ; i++)
{
results[i] = DoWork(1000000);
}
return results;
}
vector<double> Parallel()
{
vector<double> results(100);
parallel_for(0,(int)100,1,[&results](int i)
{
results[i] = DoWork(1000000);
});
return results;
}
double Sum(const vector<double>& results)
{
double result =0;
for(int i = 0 ; i < results.size();i++)
result += results[i];
return result;
}
int main()
{
DWORD start = GetTickCount();
vector<double> results = Seqential();
DWORD duration = GetTickCount() - start;
cout<<"Sequential Duration : "<<duration <<" Result : " <<Sum(results) << endl;
start = GetTickCount();
results = Parallel();
duration = GetTickCount() - start;
cout<<"Prallel Duration : "<<duration <<" Result : " <<Sum(results) << endl;
system("PAUSE");
return 0;
}
IIRC,C++11允许编译器深入到函数中,以便在编译时预计算常量表达式,甚至是像sqrt
这样的函数。因此,您的Sequential版本可能会一直优化到结果表。如果可能的话,您可能需要查看Sequential生成的程序集,看看它是否看起来过于简化,或者可能完全优化了。
关于DoWork
,没有什么是不能在编译时计算的。
问题不在于Parallel
速度慢,而在于Seqential
速度太快:
- 在
Seqential
中,编译器看到DoWork
总是会产生相同的结果,因此调用它100次的循环被优化掉,DoWork
最终只被调用一次 - 编译器不够聪明,无法以完全相同的方式优化
parallel_for
,因此它最终完成了实际工作(实际上是实际工作的100倍)
如果使DoWork
依赖于循环计数器,那么不同的调用现在将产生不同的结果,因此没有多余的调用,因此编译器将无法进行任何优化。
例如:
#include <vector>
#include <iostream>
#include <math.h>
#include <ppl.h>
#include <Windows.h>
using namespace std;
using namespace Concurrency;
double DoWork(int workload, int outer_i)
{
double result=0;
for(int i =0 ; i < workload;i++)
{
result +=sqrt((double)i * 4*3) + i* i;
}
result += outer_i;
return result;
}
vector<double> Seqential()
{
vector<double> results(100);
for(int i = 0 ; i <100 ; i++)
{
results[i] = DoWork(1000000, i);
}
return results;
}
vector<double> Parallel()
{
vector<double> results(100);
parallel_for(0,(int)100,1,[&results](int i)
{
results[i] = DoWork(1000000, i);
});
return results;
}
double Sum(const vector<double>& results)
{
double result =0;
for(int i = 0 ; i < results.size();i++)
result += results[i];
return result;
}
int main()
{
DWORD start = GetTickCount();
vector<double> results = Seqential();
DWORD duration = GetTickCount() - start;
cout<<"Sequential Duration : "<<duration <<" Result : " <<Sum(results) << endl;
start = GetTickCount();
results = Parallel();
duration = GetTickCount() - start;
cout<<"Prallel Duration : "<<duration <<" Result : " <<Sum(results) << endl;
system("PAUSE");
return 0;
}
当由Visual C++2010在Release配置下构建并在四核CPU上运行时,将打印:
Sequential Duration : 1607 Result : 1.68692e+015
Prallel Duration : 374 Result : 1.68692e+015
(顺便说一句,你真的应该考虑更好地格式化你的代码。)
可能发生的情况是,生成多个线程的开销比简单地计算结果花费更多的时间。在Release版本中,编译器能够进行大量优化,因此与设置线程和拆除线程所需的工作量相比,DoWork
内部所做的工作量要小得多。
如果您让DoWork
做更多的工作(例如通过多次循环),您将看到更符合您期望的结果。
相关文章:
- 简单C++"Hello World"程序的执行时间长
- 我使用 OpenMP 的线程越多,执行时间就越长,这是怎么回事?
- 为什么切换 for 循环的顺序会显著改变执行时间?
- cmd.exe与Powershell中C++程序的不同执行时间
- pthread执行时间比顺序执行时间差
- OpenCV 函数 cv::remap() 的执行时间更长,当程序在两者之间进入睡眠状态时
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 我需要帮助来缩短检索 SSL 证书的执行时间
- 如何测量cudaMalloc执行时间
- c++中的执行时间和检查流状态
- 为什么for循环中的异步不能提高执行时间
- 为什么 C++ openMP 程序执行时间更长
- 测量任何 Windows 可执行文件的内存使用情况和执行时间
- 需要减少我的C++代码的执行时间
- 如何在 ubuntu 上的 php 脚本中获取程序(c,c++,java,python,php)的执行时间和内存使用量?
- 在Qt中设置pixmap时的执行时间很奇怪
- 异步控制线程执行时间
- 如何对 g++ 设置执行时间限制?
- 测量 std::系统的实际执行时间(以 C++ 为单位)
- 调试和发布版本中的执行时间很奇怪