0

多线程的那点儿事(之多核编程)

 1 year ago
source link: https://blog.51cto.com/feixiaoxing/5881015
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

多线程的那点儿事(之多核编程)

推荐 原创

    多核编程并不是最近才兴起的新鲜事物。早在intel发布双核cpu之前,多核编程已经在业内存在了,只不过那时候是多处理器编程而已。为了实现多核编程,人们开发实现了几种多核编程的标准。open-mp就是其中的一种。对于open-mp还不太熟悉的朋友,可以参照​ ​维基百科​​的相关解释。

    open-mp的格式非常简单,原理也不难。它的基本原理就是创建多个线程,操作系统把这几个线程分到几个核上面同时执行,从而可以达到快速执行代码的目的。比如说,我们可以编写一个简单的例子。

    在编写open-mp程序之前,朋友们应该注意下面三点,

    (1) 使用vs2005或者以上的版本编写open-mp程序;

    (2) 编写程序的时候,选择【Property Pages】->【Configuration Properties】->【c/c++】->【language】->【OpenMp Support】,打开开关;       

    (3) 添加#include <omp.h> 声明。

    首先,我们编写简单的一个打印程序,看看结果。

#include <omp.h>

void print()
{
int i;
#pragma omp parallel for
for(i = 0; i < 100; i ++)
{
printf("%d\n", i);
}
}

    上面这段代码好像也没有什么特别的地方,但是我们可以在printf设一个断点,看看函数调用堆栈,

openmp.exe!print$omp$1() Line 14 C++
vcompd.dll!_vcomp::ParallelRegion::HandlerThreadFunc() + 0x19c bytes
vcompd.dll!_vcomp::ParallelRegion::HandlerThreadFunc() + 0xe0 bytes
vcompd.dll!_InvokeThreadTeam@12() + 0x98 bytes
vcompd.dll!__vcomp_fork() + 0x1cd bytes
openmp.exe!print() Line 11 + 0xe bytes C++
openmp.exe!wmain(int argc=1, wchar_t * * argv=0x003b5ba8) Line 22 C++
openmp.exe!__tmainCRTStartup() Line 583 + 0x19 bytes C
openmp.exe!wmainCRTStartup() Line 403 C
kernel32.dll!7c817077()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]

    我们看可以看到函数堆栈和平时看到的一般函数调用确实不一样,但这确实也说明不了什么,不过没有关系,我们可以做一个简单的测试,

#include "stdafx.h"
#include <windows.h>
#include <omp.h>

#define NUMBER 1000000000

int process(int start, int end)
{
int total;

total = 0;
while(start < end){
total += start %2;
start ++;
}

return total;
}

void test1()
{
int i;
int time;
struct {
int start;
int end;
}value[] = {
{0 , NUMBER >> 1},
{NUMBER >> 1, NUMBER}
};
int total[2] = {0};
int result;

time = GetTickCount();

#pragma omp parallel for
for(i = 0; i < 2; i ++)
{
total[i] = process(value[i].start, value[i].end);
}

result = total[0] + total[1];
printf("%d\n", GetTickCount() - time);
}

void test2()
{
int i;
int value;
int total;

total = 0;
value = GetTickCount();

for(i = 0; i < NUMBER; i++)
{
total += i %2;
}
printf("%d\n", GetTickCount()-value);
}


int _tmain(int argc, _TCHAR* argv[])
{
test1();
test2();
return 0;
}

    test1和test2完成的功能都是一样的,但是明显test1要比test2花费的时间要少很多,这明显就是多核编程的好处。所以要想实现多核编程最大程度上的并行运算,就必须把运

算拆分成n个子运算,并且尽量减少使用锁。

总结:
    (1) 这篇文章只是介绍性的博客,详细内容可以参考​​周伟明​​先生的博客;

    (2) 关于多核编程更具体的细节和方法,可以参考《​ ​多核计算与程序设计​​》这本书;

    (3) 编写多核编程需要的条件很简单,cpu支持多核、打开openmp开关、添加omp头文件,剩下的就是多多练习了;

    (4) 并行运算的时候少使用锁,否则效率会大打折扣。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK