OpenMP(Open Multi-Processing)是一套支持跨平台共享内存方式的多线程并发的编程API,使用C,C++和Fortran语言,可以在大多数的处理器体系和操作系统中运行,包括Solaris, AIX, HP-UX, GNU/Linux, Mac OS X, 和Microsoft Windows。包括一套编译器指令、库和一些能够影响运行行为的环境变量。— —维基百科OpenMP

1、相比传统多线程编程,OpenMP(多核编程)具有以下优点:

  • CPU核数拓展性问题

多核编程需要考虑程序性能随CPU核心数的拓展性,当硬件升级到多核后,能够不修改程序让程序性能增长,这要求程序中的线程数要随CPU核数变化,不能创建定数线程,否则当CPU核数超过线程数,将无法发挥CPU性能,这正是OpenMP的优势。

  • 方便性问题

多核计算时,要求将计算分摊到各个CPU核上,所有的程序都需要并行执行,对计算的负载均衡有很高的要求。操作系统API创建线程时,需要线程入口函数,很难满足这个要求,除非将一个函数内的代码分拆成多个入口函数,这将大大增加程序员的工作量,使用OpenMP不需要入口函数,可以将同一函数内代码分解成多个线程执行,也可以将一个for循环分解成多个线程执行。

  • 可移植性问题

OpenMP是标准规范,所有支持它的编译器都是执行同一套标准,不存在可移植性问题。

2、编译器支持
主流C/C++编译器,如gcc与visual C++,都内在支持OpenMP。一般都必须在程序中#inculude <omp.h>

(1)gcc编译时需使用编译选项-fopenmp。但是,如果编译为目标文件与链接生成可执行文件是分开为两步操作,那么链接时需要给出附加库gomp,否则会在链接时报错"undefined reference to omp_get_thread_num";
例如,使用Code::Blocks IDE配置如下:
Compiler Setting里的Other Options中粘贴-fopenmp
Link Setting里的Other Options中粘贴-lgomp -lpthread
如果运行时出现libgomp-1.dll丢失的问题而不能运行,就去在mingw文件夹中找到libgomp-1.dll这个文件,并将它复制到工程文件夹中。

(2)Visual C++需要在IDE(Visual Studio)的编译选项->语言->支持OpenMP。这实际上使用了编译选项/openmp。

3、示例
OpenMP是一个支持共享存储并行设计的库,特别适宜多核CPU 上的并行程序设计。

void test()
{
    int a=0;
    clock_t t1=clock();
    for(int i=0; i<100000000; ++i)
    {
        a=1+i;
    }
    clock_t t2=clock();
    printf("Time=%d\n",t2-t1);
}

int main()
{
    clock_t t1=clock();
    #pragma omp parallel for
    for(int j=0; j<2; ++j)
        test();
    clock_t t2=clock();
    printf("Total time:%d\n",t2-t1);
    
    test();
    return 0;
}

test()函数中,执行了1 亿次循环,主要是用来执行一个长时间的操作,最终执行结果:
Time=442
Time=514
Total time=515
Time=405
for循环内2次执行时间总共为515ms,后面单独执行时间为405ms,并行后效率基本提高了一倍,由于创建启动线程需要一些消耗,515ms略大于405ms也算正常。

标签: none

评论已关闭