5.1 实验目的
加深对多核处理器架构的理解;
掌握使用OpenMP进行多线程编程的基本方法;
学习Windows和OpenEuler环境下多核编程的过程和time命令;
5.2 实验平台
- 需要多核处理器的计算机和微软编程工具Visual Studio 2012。
- Taishan服务器,已经安装Openeuler操作系统,安装gcc编译器,学生用PC实验机和相关账号访问。
5.3 实验内容
1. Windows环境下的多核编程
1)Visual Studio环境中,新建一个空项目,在项目属性中打开OpenMP支持即可(如图所示)。
2)添加项目中的cpp源文件,代码如下:
#include <iostream>
#include <time.h>
using namespace std;
void test()
{
int a = 0;
for (int i=0;i<100000000;i++)
a++;
}
int main()
{
clock_t t1 = clock();
for (int i=0;i<8;i++)
test();
clock_t t2 = clock();
cout<<"time: "<<t2-t1<<endl;
getchar();
}
查看记录一下运行时间(这是完全串行执行的时间)。
3)然后在for 循环前面增加一行:#pragma omp parallel for
即代码如下:
#include <iostream>
#include <time.h>
using namespace std;
void test()
{
int a = 0;
for (int i=0;i<100000000;i++)
a++;
}
int main()
{
clock_t t1 = clock();
#pragma omp parallel for
for (int i=0;i<8;i++)
test();
clock_t t2 = clock();
cout<<"time: "<<t2-t1<<endl;
getchar();
}
再查看记录一下运行时间(这是把for循环部分变成多线程并行执行的时间。线程数目就是你电脑CPU的默认线程数目)。分析一下程序性能提升了多少。
执行时间从1305减小至234,多线程并行比完全串行减少了82%。
2. Openeuler环境下的多核编程
1)在实验机器上,使用学生账号通过SSH方式远程连接Taishan服务器 (用户名:stud001——stud140,密码:1)
2)使用lscpu命令,了解Taishan服务器CPU信息,包括CPU(s): 、Thread(s) per core、Core(s) per socket、Socket(s)
3)使用vim编辑器,创建程序threads.c,并使用gcc编译该程序
4)运行threads程序,查看并记录运行结果
5)使用time命令查看real时间(墙上时间(wall clock time)
6)在threads.c的基础上进行修改,加入多线程指令,了解OMP用法及默认线程数。建立threadsOMP.c程序,使用gcc -fopenmp命令编译后,运行并查看程序结果。观察程序运行时间的变化,并分析原因。
可以看到,96个线程的程序运行时间并不比完全串行执行的时间少,原因可能是clock()测量所有线程的累积时间,上下文切换影响到了多线程的执行速度。
7)使用time命令运行threadsOMP程序,查看墙上时间,比较与之前程序的差异。
可以看到,96个线程的程序运行时间比完全串行执行的时间多约0.05。但是,96个线程的程序运行的real时间比完全串行执行的real时间少了约87%,user用户CPU时间不相上下,sys系统CPU时间比完全串行执行的时间多了线程切换时间。可见,多个线程可明显降低real执行时间,但是由于上下文切换等原因,程序运行时间反而比完全串行执行的时间长。
8)修改程序使用不同线程数(变量nt)运行程序观察程序结果及墙上时间的变化。列表记录nt为1、2、4、6、8、9、10、32、96时的运行时间
线程数(nt=) | 程序结果Time | Real(s) | User(s) | Sys(s) |
1 | 2.537147 | 2.485 | 2.560 | 0.009 |
2 | 2.560795 | 1.244 | 2.554 | 0.008 |
4 | 2.580562 | 0.672 | 2.582 | 0.000 |
6 | 2.549261 | 0.624 | 2.545 | 0.008 |
8 | 2.541675 | 0.314 | 2.290 | 0.268 |
9 | 2.535507 | 0.314 | 2.552 | 0.004 |
10 | 2.541194 | 0.314 | 2.325 | 0.231 |
32 | 2.537887 | 0.314 | 2.537 | 0.008 |
96 | 2.534621 | 0.314 | 2.549 | 0.008 |
可以看到,1个线程的程序结果Time与32个线程的程序结果Time差不多,从线程数为2开始,线程数越多,程序结果Time越小;从线程数为1到线程数为8,程序运行的real时间大幅减少,而从线程数为8往后,线程数的增加不会对程序运行的real时间产生较大影响;线程数的变化不会对程序运行的user用户CPU时间和sys系统CPU时间产生较大影响。
-------------------------------------------------------------------------------------------------------
最后一点碎碎念:如果各位有发现本文有哪处有误或理解不当的地方,敬请指正。