1

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

3 回答 3

2

IIRC,C++11 允许编译器深入到函数中,以便在编译时预先计算常量表达式,甚至像sqrt. 因此,您的 Sequential 版本可能会一直优化到结果表。如果可能,您可能想查看为 Sequential 生成的程序集,看看它是否看起来过于简化,或者可能完全优化掉了。

在编译时没有什么DoWork不能计算的。

于 2012-03-03T05:04:51.647 回答
1

可能发生的是,产生多个线程的开销比简单地计算结果要花费更多的时间。在发布版本中,编译器能够进行大量优化,因此与DoWork设置线程和拆除线程所需的工作量相比,内部完成的工作量要小得多。

如果您DoWork做更多的工作(例如通过多次循环),您将看到更符合您期望的结果。

于 2012-03-03T05:01:27.123 回答
1

问题不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 构建并在四核 CPU 上运行时,将打印:

Sequential Duration : 1607  Result : 1.68692e+015
Prallel Duration : 374  Result : 1.68692e+015

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

于 2012-03-03T15:04:45.277 回答