欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

并行计算究竟是哪些在并行

程序员文章站 2022-03-06 13:56:51
...

入门参考:https://www.cnblogs.com/hantan2008/p/5961312.html

今天在弄一个多线程的事情,由一个线程转为多线程,固定的任务所花费的时间基本上没有减少,多线程不管是2个还是4个(4核电脑),单线程花费19分30秒,2线程花费17分10秒,4线程花费16分30秒,这个效率提升的太少了,为了提高效率,搜索并行计算的文章,之间有个工程也用了一下并行计算,但由于依赖omp那个库文件,导致有的电脑上没有办法运行,所以也就直接屏蔽掉了,今天由于任务繁重(上面的时间只是测试了效率,实际上任务数量可能是上面的200倍以上),所以还是想看看并行计算是否可行。

下面的试验环境:

vs2015,64位mfc工程,win7 64bit系统

 

通过搜索上面的那个网址,基本形式知道咋写了,于是有了下面的入口代码:

void BdBody(const int tindex)
{
	CString strText;
	strText.Format(TEXT("线程编号:%d.\n"), tindex);
	OutputDebugString(strText);
}

int tCount = 4;
void BdBodyP()
{
	int im = 0;
#pragma omp parallel num_threads(tCount)
	for (im = 0; im < tCount; im++)
	{
		BdBody(im);
	}
}

在运行时,发现和想像中的不一样,预期打印为:

线程编号:0.
线程编号:1.
线程编号:2.
线程编号:3.
 

实际打印却是:

线程编号:0.
线程编号:1.
线程编号:2.
线程编号:3.
线程编号:0.
线程编号:1.
线程编号:2.
线程编号:3.
线程编号:0.
线程编号:1.
线程编号:2.
线程编号:3.
线程编号:0.
线程编号:1.
线程编号:2.
线程编号:3.
 

这样子看,是每个线程都for循环了一遍,找个方法试试:

#pragma omp parallel num_threads(tCount) private(im)

这一行后面加个private(im),运行,结果打印没变,说明这样是无效的。那改成如下的样子试试:

void BdBodyP()
{
	int im = 0;
#pragma omp parallel num_threads(tCount)
	//for (im = 0; im < tCount; im++)
	{
		BdBody(im++);
	}
}

结果发现,打印可能不规律,其中的一次打印如下:

线程编号:0.
线程编号:1.
线程编号:1.
线程编号:3.
 

说明 im++ 并不是按顺序执行的,多种尝试都不行,没办法,只好在线程里面加索引了,大致如下:

// m_bdThreadIndex 在调用BdBodyP()之前,会置为0,m_csVec为互斥变量
void BdBody()
{
	int tid = 0;
	{
		CAutoCri cri(m_csVec);
		tid = m_bdThreadIndex++;
	}

	CString strText;
	strText.Format(TEXT("线程编号:%d.\n"), tindex);
	OutputDebugString(strText);
}

int tCount = 4;
void BdBodyP()
{
#pragma omp parallel num_threads(tCount)
	BdBody();
}

这样加之后,发现好了,多次测试也都正常了:

线程编号:0.
线程编号:1.
线程编号:2.
线程编号:3.
 

通过这个调试,终于弄明白了并行的写法,是对它下面的整个部分进行“并行”,而不是像我看到的所有网上搜索出来的那样,所以网上的写法很容易让人产生误解。

相关标签: 并行计算