*怎么在Linux上运行OpenMP程序?
> 只需要安装支持OpenMP的编译器即可,比如GCC 4.2以上版本(好像Fedora Core带的部分4.1版本也支持),或者ICC(我用的version 9.1是支持的,其他没试过)。
*怎么缺点编译器是不是支持OpenMP?
> 看编译器安装路径下/include目录里有没有omp.h。(建议使用命令#locate omp.h 这样你就会知道的)
*怎么区分OpenMP程序?
> 程序中有没有以下内容:
> #include <omp.h>
> #pragma omp ...
*怎么编译OpenMP程序?
> gcc -fopenmp [srcfile] -o [dstfile]
> icc -openmp [srcfile] -o [dstfile]
*怎么运行OpenMP程序?
> 编译后得到的文件和普通可执行文件一样可以直接执行。
*怎么设置线程数?
> Method1:在程序中写入set_num_threads(n);
> Method2:export OMP_NUM_THREADS=n;
> 两种方法各有用处,前者只对该程序有效,后者不用重新编译就可以修改线程数。
----
#include <omp.h>
int main()
{
results:
$ export OMP_NUM_THREADS=8
$ ./hello
[1] Hello
[0] Hello
[3] Hello
[2] Hello
[7] Hello
[4] Hello
[6] Hello
[5] Hello
#include <stdio.h>
#include <time.h>
void main ()
{
#include <stdio.h>
#include <time.h>
#include <omp.h>
void main ()
{
result:
Sequential version:
Pi = 3.141592653589792 (1000000000 steps), 13900000 ms
Parallel version for 8 threads:
Pi = 3.141592653589794 (1000000000 steps), 1820000 ms
从结果可以看到8线程的speedup=7.64,接近线性。因为这个程序本身具有良好的并发性,循环间几乎没有数据依赖,除了sum,但是用reduction(+:sum)把对于sum的相关也消除了。而且实验平台本身就有8个处理器核。
当把OMP_NUM_THREAD改成1之后再看看结果:
Pi = 3.141592653589792 (1000000000 steps), 14610000 ms
比串行程序增加了5.1%的overhead,证明增加的1句语句(主要是做任务分配)是有代价的。
再看看把OMP_NUM_THREAD改成大之后的结果:
64 Threads: Pi = 3.141592653589792 (1000000000 steps), 230000 ms - speedup=60.43
128 Threads: Pi = 3.141592653589795 (1000000000 steps), 120000 ms - speedup=116.83
256 Threads: Pi = 3.141592653589794 (1000000000 steps), 120000 ms - speedup=116.83
//这是什么牛机器啊!!!大汗!!!让我怀疑这里出了问题!!!
假设结果是正确的,那么可以看到这个系统的并发极限是128!
我原本想证明的是线程切换是有代价的,所以如果线程数> 处理器数(并不等于有几个CPU),加速比就会下降。
但是当线程从128增加到256的时候时间居然也没有变。。。
其实可以在一个单处理器(单核处理器且不支持超线程)上试一下一个8线程的程序会比1线程的程序运行时间长。
> 只需要安装支持OpenMP的编译器即可,比如GCC 4.2以上版本(好像Fedora Core带的部分4.1版本也支持),或者ICC(我用的version 9.1是支持的,其他没试过)。
*怎么缺点编译器是不是支持OpenMP?
> 看编译器安装路径下/include目录里有没有omp.h。(建议使用命令#locate omp.h 这样你就会知道的)
*怎么区分OpenMP程序?
> 程序中有没有以下内容:
> #include <omp.h>
> #pragma omp ...
*怎么编译OpenMP程序?
> gcc -fopenmp [srcfile] -o [dstfile]
> icc -openmp [srcfile] -o [dstfile]
*怎么运行OpenMP程序?
> 编译后得到的文件和普通可执行文件一样可以直接执行。
*怎么设置线程数?
> Method1:在程序中写入set_num_threads(n);
> Method2:export OMP_NUM_THREADS=n;
> 两种方法各有用处,前者只对该程序有效,后者不用重新编译就可以修改线程数。
----
Example 1 - hello.c
#include <omp.h>
int main()
{
#pragma omp parallel
printf( "[%d] Hello\n ", omp_get_thread_num());
return 0;}
results:
$ export OMP_NUM_THREADS=8
$ ./hello
[1] Hello
[0] Hello
[3] Hello
[2] Hello
[7] Hello
[4] Hello
[6] Hello
[5] Hello
Example 2: 矩阵拟合法计算Pi
#include <stdio.h>
#include <time.h>
void main ()
{
time_t start, finish;
static long num_steps = 1000000000;
double step;
int i;
double x, pi, sum = 0.0;
step = 1.0/(double) num_steps;
start = clock();
for (i=0;i < num_steps; i++)
{
x = (i+0.5)*step;}
sum = sum + 4.0/(1.0+x*x);
pi = step * sum;
finish = clock();
printf( "Pi = %16.15f (%d steps), %ld ms\n ", pi, num_steps, finish-start );
return;
}
#include <stdio.h>
#include <time.h>
#include <omp.h>
void main ()
{
time_t start, finish;}
static long num_steps = 1000000000;
double step;
int i;
double x, pi, sum = 0.0;
step = 1.0/(double) num_steps;
start = clock();
#pragma omp parallel for reduction(+:sum) private(x)
/*只加了这一句,其他不变*/
for (i=0;i < num_steps; i++)
{
x = (i+0.5)*step;}
sum = sum + 4.0/(1.0+x*x);
pi = step * sum;
finish = clock();
printf( "Pi = %16.15f (%d steps), %ld ms\n ", pi, num_steps, finish-start );
return;
result:
Sequential version:
Pi = 3.141592653589792 (1000000000 steps), 13900000 ms
Parallel version for 8 threads:
Pi = 3.141592653589794 (1000000000 steps), 1820000 ms
从结果可以看到8线程的speedup=7.64,接近线性。因为这个程序本身具有良好的并发性,循环间几乎没有数据依赖,除了sum,但是用reduction(+:sum)把对于sum的相关也消除了。而且实验平台本身就有8个处理器核。
当把OMP_NUM_THREAD改成1之后再看看结果:
Pi = 3.141592653589792 (1000000000 steps), 14610000 ms
比串行程序增加了5.1%的overhead,证明增加的1句语句(主要是做任务分配)是有代价的。
再看看把OMP_NUM_THREAD改成大之后的结果:
64 Threads: Pi = 3.141592653589792 (1000000000 steps), 230000 ms - speedup=60.43
128 Threads: Pi = 3.141592653589795 (1000000000 steps), 120000 ms - speedup=116.83
256 Threads: Pi = 3.141592653589794 (1000000000 steps), 120000 ms - speedup=116.83
//这是什么牛机器啊!!!大汗!!!让我怀疑这里出了问题!!!
假设结果是正确的,那么可以看到这个系统的并发极限是128!
我原本想证明的是线程切换是有代价的,所以如果线程数> 处理器数(并不等于有几个CPU),加速比就会下降。
但是当线程从128增加到256的时候时间居然也没有变。。。
其实可以在一个单处理器(单核处理器且不支持超线程)上试一下一个8线程的程序会比1线程的程序运行时间长。