我开始在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;
}
答案 0 :(得分:2)
IIRC,C ++ 11允许编译器深入到函数中,以便在编译时预先计算常量表达式,甚至像sqrt
这样的函数。因此,您的Sequential版本可以一直优化到结果表。如果可能的话,您可能希望查看为Sequential生成的程序集,看看它是否过于简化,或者可能完全优化掉。
DoWork
无法在编译时计算出来。
答案 1 :(得分:1)
可能发生的事情是,产生多个线程的开销比简单地计算结果花费的时间更多。在发布版本中,编译器能够进行大量优化,因此与设置线程并将其拆解所需的工作量相比,DoWork
内的工作量要小得多。
如果您让DoWork
做更多工作(例如循环多次),您会看到更符合您期望的结果。
答案 2 :(得分:1)
问题不在于Parallel
缓慢,而在Seqential
Seqential
中,编译器发现DoWork
将始终产生相同的结果,因此调用它100次的循环被优化掉,DoWork
最终称为只有一次。parallel_for
,因此它最终会完成实际工作(事实上实际工作的次数是 100倍)。 / LI>
如果你使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
(顺便说一句,你应该考虑更好地格式化你的代码。)