Debug和Release版本中的执行时间过长

时间:2012-03-03 04:57:05

标签: c++ c++11 ppl

我开始在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;
}

3 个答案:

答案 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

(顺便说一句,你应该考虑更好地格式化你的代码。)