使用tbb进行数字积分法求π,串行程序在最后。

横云断岭
博客专家认证
2010-01-04 11:45:52
数字积分法求π,串行程序在最后。
开始时,long num_steps 是1000000000.则程序运行时间有时是50多秒,有时是24秒。
我以为是要求的内存太大了,就改为long num_steps = 100000000;
设置GrainSize = 50000000;或者GrainSize = 10000000;,或者auto_partitioner(),都是有时时间是5秒,有时是2.**秒。
请教!
CPU:AMD5000
系统:windows7
编译工具:VS2008
在英文论坛发了个帖子..没人理..悲剧..

是不是CPU的问题?不过我看那个支持列表..应该AMD5000没问题吧..
而且我观察CPU的使用率,在计算时都是100%的.
支持的硬件
• 英特尔® 奔腾® 4 处理器家族
• 英特尔® 奔腾® D 处理器家族
• 英特尔® 至强® 处理器家族
• 英特尔® 酷睿™ 处理器家族
• 英特尔® 酷睿™2 处理器家族
• 英特尔® 安腾® 处理器家族(仅限 Linux* 系统)
• 非英特尔® 处理器与上述处理器兼容

#include <iostream>
#include <time.h>
#include "tbb/parallel_reduce.h"
#include "tbb/task_scheduler_init.h"
#include "tbb/blocked_range.h"

using namespace std;
using namespace tbb;

int Nthreads = 2;
int GrainSize = 50000000;
long long num_steps = 100000000;

class CMyPi
{
double *const my_step;
public:
double sum;
void operator()(const blocked_range<size_t>& r);
CMyPi(CMyPi& x, split);
void join(const CMyPi& y);
CMyPi(double *const step);
};

CMyPi::CMyPi(double *const step):my_step(step)
{
sum = 0.0;
}
CMyPi::CMyPi(CMyPi &x, tbb::split):my_step(x.my_step)
{
sum = 0.0;
}
void CMyPi::join(const CMyPi &y)
{
sum += y.sum;
}
// step = 1.0/(double)num_steps;
// for (i=0; i < num_steps; i++)
// {
// x = (i+0.5)*step;
// sum = sum + 4.0/(1.0 + x*x);
// }
void CMyPi::operator ()(const blocked_range<size_t>& r)
{
double x = 0.0;
for(int i = r.begin();i!=r.end();++i)
{
x = (i+0.5)* (*my_step);
sum+=4.0/(1.0+x*x);
}
}

int main(int argc, char* argv[])
{
clock_t start, stop;
double pi;
double width = 1./(double)num_steps;

CMyPi step((double *const)&width);
task_scheduler_init init(task_scheduler_init::deferred);

start = clock();
init.initialize(Nthreads); //设置TBB线程数
parallel_reduce(blocked_range<size_t>(0,num_steps,GrainSize), step);
// parallel_reduce(blocked_range<size_t>(0,num_steps), step, auto_partitioner());
pi = step.sum*width;
stop = clock();

cout << "The value of PI is " << pi << endl;
cout << "The time to calculate PI was " << (double)(stop-start)/CLOCKS_PER_SEC << " seconds\n";
system("pause");
return 0;
}

//#include <stdio.h>
//static long num_steps=100000;
//double step;
//void main()
//{ int i;
// double x, pi, sum = 0.0;
// step = 1.0/(double)num_steps;
// for (i=0; i < num_steps; i++)
// {
// x = (i+0.5)*step;
// sum = sum + 4.0/(1.0 + x*x);
// }
// pi = step * sum;
// printf(“Pi = %f\n”,pi);
//}

...全文
291 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
横云断岭 2012-09-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

我什么在我64bit I5 win8上跑, 串行是0.00008s,并行使0.5s?????????????????
[/Quote]
这个也许和cpu的cache的大小和不同核之间的共享方式有关。
可能要调整程序中的一些数据,来对应cache的大小。
greensky7000 2012-09-28
  • 打赏
  • 举报
回复
我什么在我64bit I5 win8上跑, 串行是0.00008s,并行使0.5s?????????????????
wanglei5695312 2010-01-05
  • 打赏
  • 举报
回复
计数就用tick_count::now()吧,再计算一下吧,你那个clock()粒度太大
wanglei5695312 2010-01-05
  • 打赏
  • 举报
回复
tbb2.2应该支持lambdar函数吧,
parallel_for(blocked_range<int>(0, num_steps, 5000),
[] (const blocked_range<int> &r) {
for (int i = r.begin(); i != r.end(); ++i){
x = (i + 0.5)*step;
sum = sum + 4.0/(1. + x*x);
}
tbb::spin_mutex::scoped_lock lock(myMutex);
pi += step *sum;
});
intel 编译器和vc++编译器怎么都是这个错误啊,请教了?我是在vs2005下
error: expected an expression [] (const blocked_range<int> &r) {
怎么有的书上说应该是
<> (const blocked_range<int> &r) {
lambdar函数应该是[]还是<>啊?
intel_iclifort 2010-01-05
  • 打赏
  • 举报
回复
另外, 请说明一下使用的TBB版本
intel_iclifort 2010-01-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 yshuise 的回复:]
TBB 的全名是 “Intel Threading Building Blocks”,应该是针对intel处理器的优化吧。

[/Quote]

这个是误解了, TBB最初是由Intel的工程师发起和创建的项目, 目前已经是Open Source了, 它是基于C++的.


当然, Intel还会再发布一个TBB的binrary版本, 这个会针对x86架构有些性能优化
yshuise 2010-01-05
  • 打赏
  • 举报
回复
TBB 的全名是 “Intel Threading Building Blocks”,应该是针对intel处理器的优化吧。
横云断岭 2010-01-05
  • 打赏
  • 举报
回复
这个我貌似发现问题了,当设置int Nthreads = 8 时,程序正常了。运行时间是2.*了。
当设置int Nthreads = 4 时,要比 8 时要慢一点。在我的电脑上8线程是最合适的。
真是个奇怪的问题。
在xp下运行int Nthreads = 2 的程序,总是5.*的时间,只有在windows7下才很少情况下出现2.*。这个听说windows7在进程调度方面有些改进。不知道是不是和这个有关。
晕,猛然发现回复5楼的帖子中,粒度应该是太大。。
横云断岭 2010-01-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 intel_iclifort 的回复:]
另外, 请说明一下使用的TBB版本
[/Quote]
应该是2.2吧。。前一阵子下的。
[Quote=引用 5 楼 wanglei5695312 的回复:]
计数就用tick_count::now()吧,再计算一下吧,你那个clock()粒度太大
[/Quote]
这个粒度的确大小。。

566

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧