请并行程序设计或者多线程程序设计高手解决一个do-while模型的并行

chbq1210 2006-09-29 03:19:46
能不能用OpenMP设计一个并行do-while模型的算法,让创建线程放在do-while外面,也就是只创建和销毁一次线程,而不是放在do-while内部,因为do-while可能执行成百上千次,如果放在内部的话成百上千次创建和销毁线程的开销往往比并行减少的时间还大。
如果OpenMP不能解决,如果有其它技术解决方案如Win32多线程技术也行。
#pragma omp parallel for (…) //创建线程
{
do
{
pjn=0;
for(i=0;i<LMN;i++)
{
//我课题这里是要采用流水线并行的,不过可以先设计出一个解决外层do-while并
行的算法,最后再考虑内部的流水线并行(流水线并行已经实现)。
Error=GetError(i); //取得误差
If(Error>Delta)//如果误差大于固定值,则修正
{
pjn++;
Func_Modify(i); //对与i相关的元素进行修正。
}
}
}while(pjn!=0);
}//在这里要销毁。

这个问题困了我一两个月了,请大家多多指点,不胜感谢。
...全文
726 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
danscort2000 2006-10-21
  • 打赏
  • 举报
回复
回答: 我对您的具体操作过程不清楚,但大概意思是并行操作,也就是一次轮循找出所有的误差,然后进行修正[如果需要的话],下一次轮循必须等到上一次所有操作完成才可以开始,可能还要计算第一个和中间N个操作间的很小的时间误差,
如果是我理解的这样,那么很好解决,不过我使用的是MFC库,在WIN 9X/NT/2000/XP/2003系统下的模型,如果是LINUX,因为使用CLONE,我不熟悉,但是原理应该一样

//全局变量
int *i_p=new int[你需要检测的参数的总数,几百万]
CWinThread * p_workthread;[你开启实际进行检测和修正操作的线程指针]
volatile long int m_count=0;
volatile long int m_curtick=0;
实现代码和流程
主线程
采用轮循结构

int i;
int j;


while(1)//1修改为你的退出条件
{

memset(i_p,0,你的几百万个检测总数)
j=0;
m_curtick++;
for( i=0; i<你的几百万需要检测的总数; i++)
{
if( i位置需要检测)
{
//本次需要等待的操作数累加,原子减操作由工作线程来完成
::InterlockedIncrement(&m_count);
//给工作线程发送消息,J是具体需要操作的参数的编号,消息你自己随便定义一个好了,例如WM__USER+100
p_workthread->PostThreadMessage(WM_YOUR_DEFINE_MSG,j,j);
}

}

while(m_count!=0) //如果本次循环发现的需要修正的操作还没有全部完成,那么等待完成
Sleep(20);
//现在保证本次操作全部完成,继续下一个循环检测......

}

//将所有检测和修正操作放到工作线程中去
UINT MyWorkThread(LPVOID pParam)
{
MSG msg;//线程接收的消息结构,WIN32体系,UNIX/LINUX没这个东西
int num;
long int lasttick=0;
long int curtick=0;
while(1)//1,可以修改成你自己定义的退出变量,加VOLATILE修饰
{
::GetMessage(&msg);
switch(msg.message)
{
case WM_YOUR_DEFINE_MSG: //由主线程发送的需要修改的消息
curtick=m_curtick;//判断本次操作的循环是否是同一个
if(curtick!=lasttick)
{
//重新计算循环开始时间
.......
}
num=(int)msg.lParam;
//检测NUM是否合法
//调用你自己的检测和修正函数,并传递NUM位置
//完成修改后,调用原子减操作
::InterlockedDcrement(&m_count);
lasttick=curtick;//修改循环是第几轮
break;
......
}
}
}
//--------------------------
如果需要针对4个或者更加多的内核CPU,那么你可以增加一个智能选择函数,
用一个主线程,N个工作线程来配合完成,这应该不是问题吧

chbq1210 2006-10-17
  • 打赏
  • 举报
回复
您好,感谢您的回复,不过我还是不太明白您的意思,我现在是在用两个线程在做,按照我的模型,每个线程都要进入修正部分,事实上修正倍分占的时间也不是很长,而LMN是百万级以上的,在求每一个节点的误差时其实也是一个与修正差不多耗时的代码,事实上对于每次迭代,并不一定所有的LMN个节点都会进行修正,可能修正的只是几百或者几千个,所以如果把修正部分用一个线程来单独做也会出现线程间的平衡,本来intel扩展了一个workqueuing模型可以做do-while,但由于我的代码是有流水线并行,有依赖关系,再加上我上面的说分布不均,所以应用的结果不但不正确,速度也不能提高。
没有找到您的邮件地址,所以只有这样给你发送消息,我的邮件地址是:chbq@smail.hust.edu.cn,很希望就这样问题和你进行讨论。感谢您提供帮助。
danscort2000 2006-10-12
  • 打赏
  • 举报
回复
//我课题这里是要采用流水线并行的,不过可以先设计出一个解决外层do-while并
行的算法,最后再考虑内部的流水线并行(流水线并行已经实现)。
Error=GetError(i); //取得误差
If(Error>Delta)//如果误差大于固定值,则修正

这不是很简单的吗?
有几个核心就并发几个WORK THREAD好了
每个WORK THREAD指定执行一定范围内的流水号
不需要执行DO-WHILE
将纠正部分代码放到线程中去执行
主线程只要等待一个结束事件,或者干脆用WHILE(1)
{
TEST IF ACTIVE
SLEEP(1000);
}

568

社区成员

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

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