多核与GPU编程附录

所需积分/C币:50 2017-05-09 15:51:59 21.34MB PDF
0
收藏 收藏
举报

《多核与GPU编程》一书的附录
附录BMh 运行MP|程序:准备与配置步骤 B.1准备步骤 使用网络工作站(NoW)作为并行平台的问题是,每个工作站需要提供一个远程启动进 程的机制。实现这一机制的常用方法或者是通过远程 Shell(RSH),或者是通过安全 Shell (SSH)。前者已经不再使用了,因为它太不安全(密码以明文的方式传递)。 为了执行一个MPI程序,SSH通常会需要在每个工作站上有一个交互式的登录进程! 要避免这种漫长且无聊的过程,方法是通过一个代表我们执行登录事务的身份验证代理 接下来的步骤可以实现这一目标。 1.创建一个身份验证密钥,即一个可以唯一识别你的用户账号的数字 s sSh-keygen -t dsa 会提示你输入一个控制你的密钥访问权限的密码短语。这没有必要与你的用户账户密 码一致。ssh- keygen指令分别生成公钥以及私钥两个文件(~表示你的主目录) / ssh/id dsa c/ssh/id_dsa. pub 2.拷贝公钥~/.ssh/id_dsa.pub文件 s cp -/. ssh/id_dsa. pub - /.ssh/authorized keys2 3.确保被拷贝的文件具有正确的权限: s chmod go-rwx -/. ssh/authorized keys2 4.步骤1~3只需要执行一次(除非你忘记了密码短语)。在运行每个MPI会话前,需 要启动代理程序 4 多核与GPU编程:工具、方法及实践 s ssh-agent bash 或者 ssh- a gent事 SHELL 5.通过如下指令将密钥交给代理 s ssh-add 现在你几乎准备好运行你的第一个并行程序了。使用工作站网络作为并行平台需要另 外一个步骤,这会在下一节讲述。 B2MPI程序部署的计算节点发现 将MPI程序部署到NoW上需要对应的IP地址以及DNS名称列表。对于那些可以访 问到专用集群或者超级计算设施的幸运儿,可用节点的问题在很大程度上由他们所在的研 究所解决和管理。然而,当使用通用的内部网络且网络中的机器使用动态IP时,在每次启 动程序前需要编译机器列表。本节将讲述生成机器列表的步骤。 B2.1通过hmap工具发现主机 网络映射(nmap)程序是一个用于发现主机以及计算机网络上服务的安全的扫描器。它 主要应用在漏泂检测中,因此它已经被系统管理员(系统安全)以及黑客(入侵)使用。出 于这个原因,在内部网络中使用ηmap可以被监控或被控制。在尝试使用在此描述的指令或 脚本时,最好事先与所在地的系统管理员就nmap的使用情况进行商讨。 付于当前问题,nmap会在用户提供的IP地址范围内检测可用主机并且罗列出这些机器 所打开的端口。后者是为了确保对运行sshd的主机的安全识别,这是因为由nmap所支持 的OS检测并不总是准确的。除此之外,出于安全原因,许多操作系统会对请求进行哄骗回 复,而nap利用这些请求去推演主机身份。 如果我们假设将会运行MPI程序的机器IP地址在10.25.32*到10.25.34.*之间,那么 如下语句会产生一个被部署的候选机器列表。 nmap-0 g hosts10.25.32.*10.25.34.* s grep ssh hosts I gawk -F ' print $2)'> hostswithssh 第一行指令中的-0G开关可以将nmap的输出保存到一个文本格式文件(已指定了 hosts)中,以供grep工具过滤。下一行指令则是将输出文件中包含ssh的行过滤出来。这 些行之后被传递给qawk工具以提取第二列信息,及对应主机的IP。 主机随后可以通过以下指令验证,即用户凭据适合登录。该行指令尝试在每个主机中 运行echo指令 s for f in cat hostswithssh ' do ssh sf echo sf: done 附录B运行MPI程序:准备与配置步骤心5 如B.1节所示,这行指令只有在SSH代理开启之后才能尝试。 B22自动生成 hostfile 个 MPI hostfile包含每个主机所支持的进程数量。这主要是为了使主机利用率达到最 大,因为内核数量可以被集成到MPI的部署进程中。 以下脚本会将前一节所描述的步骤以及 Linux系统的/proc伪文件系统中的有用信息 结合起来,自动生成合适的 hostfile # bin/ bash 2 File: hostbuild sh 4 tmp File=/tmp/hosts whoam s tmp File2=/tmp /hosts2_ whoami 7 Discover all the hosts matching the supplied ip pattern (s) 8 nmap -oG sitmpFile) $s >/dev/nul 10 Get the ip of the localhost. It has to participate in the launch config head -n 2 ta gawk -Fade { print$2}’gawk (print $11'>$tmpFile2 13 Filter out the hosts not supporting Ssh p ssh $ i gawk (print $21 $ File2) 16 Remove -if it exists-a duplicate entry for localhost nig stmpFile2 $itmpFile Get the s for each h In the temporary file for h in 21 do res='ssh -o ConnectTimeout=5 -o BatchMode=yes -o< StrictHostKeychecking=no $h cat /proc/cpuinfo i grep processor wc|gawk’{ print$1} #f Output the Ip only if there is a valid response from the t previous command f [Sres:-01 echo "Sh slots= Sres 29 done 在前面脚本中创建出一些新东西的指令行如下。 第11行:将运行此脚本的主机的IP地址插入 hostfile中。 第17行:使用uniq实用工具将重复的条目从 hostfile中删除。这只涉及1 localhost。 第20~29行:循环遍历临时 hostfile文件上的全部条目,并且输出对第22行通过 ssh发出的指令做出回应的条目。 第22行:以非交互的方式(-0 BatchMode=yes)运行sh指令,最长等待周期为5秒 6 多核与GPU编程:工具、方法及实践 (- o Connecttimeout=5),不需要执行严格的秘钥检查(- o StrictHostKey Checking=ηo)。 每个主机需要运行管道cat/proc/ cpuinfo grep processor|wc|gawk'{ print$1}’。如 果成功,该管道返回操作系统所识别的处理内核数量。值得注意的是,超线程內核与 非超线程内核没有区别 该脚本可以通过如下方式使用,即只须提供一个由空格分开的IP地址列表以及将输出 结果重定向到一个文件中 bash hostbuild sh.25.32* 10.25. 34.*k my Hosts 附录 C:ponder C 测量时间 C1引言 在计算性能和跟踪用户系统中事件时,例如调试时,高分辨率的时间测量非常重要 毕竟我们将线程、GPU计算等引入应用程序的根本目的就是缩短系统运行时间。 测量时间可以分为绝对的和相对的。绝对的时间(也即普遍意义上的时间的概念)可以 追溯到牛顿那个时代。但是很多人认为在后广义相对论时代,已经没有类似绝对时间这样 的事情了。我们也没有采用绝对时间这一概念,因为我们所关心的是时间的跨度,即相对 时间。 后面小节中普遍采用的模式是求时间戳差值。各个库中提供的时间测量函数均是测定 当前时间与一个特定时间点的时间差,这个特定的时间点可以是程序开始执行时,系统启 动时,或者某一特定时间(通常是1970年1月1日00:00)等。 需要注意的是,系统时钟可以被操作系统的时间调整功能改变。许多系统都有守护进 程,它通过NTP协议定期地将本地时间与 Internet时间服务器上的时间同步。实时的时钟 调整通常是每天做一次,但它们也可能会产生明显错误的时间戳差值,如非常巨大的或者 负的时间戳差值。在这种情况下,实验结果只能丟弃,然后重新进行实验。 C2 POSIX高精度计时 POSIX( Portable Operating System Interface for UNIX,UNIX可移植操作系统接口)是 个IEEE标准,它定义了一系列操作系统应该为应用程序提供的接口。 POSIX实现了程序 源代码层的跨平台兼容性。使用 POSIX函数编写的程序可以在所有支持 POSIX的系统上 8 多核与GPU编程:工具、方法及实践 重新编译和执行。 POSIX也定义了用于精确计时的函数: int clock-getres(clockid-t clk_id, struct timespec *res); / returns the clock resolution of the specified clock int clock getti me(clockidt clk_id, struct timespec tp);//return t the time according to the specified clock 这些函数定义在头文件time.h中,在程序链接库的时候也需要添加-1rt选项。 这两个函数都会在执行成功时返回0,失败时返回-1,它们所操作的数据类型的说明 如下所示。 clocked_t:标识待査询时钟的整数值。无论对于整个系统或者进程,甚至是线程 都可以支持多个时钟。其中有几个很重要的,用符号常量表示如下。 CL0CK_ REALTIME:系统范围内的实时时钟。 CLOCK M0N0T0NIC:代表从过去某个不固定的时间点开始的绝对时间差。 CL0CK_ PROCESS_ CPUTIME_ID:进程从开始到当前代码,系统CPU花费的时间。 struct timespec:包含两个整型变量,一个以秒表示时间的整数部分,一个以纳秒 表示时间的小数部分 struct timespec i time t tv sec; /米 seconds*/ long tv nsec. 米 nanoseconds 所以,对于一个 timespec的实例ts,时间具体的值为:ts. tv sec+ts. ty nsec/10000。 通过使用这些函数,我们可以写一系列函数以方便地测试事件的执行时间。时间可以 用整数来表示纳秒,也可以用浮点数来表示秒,如代码清单C-1所示。 代码清单C-1使用POSⅨ高精度计时函数测量执行时间的例子。 oclock_seC(或 hrclock nsec) 返回当前时间与time0sec(或time0_nsec)之间的时间差,用秒数(或纳秒数)表示 / File: clock_example. cpp 3 #include <time. h> long time0_nsec =0 7 double timeo sec= o //************米***米****米****米米**米米****米*冰**米冰米米 10 double hrclock sec o t i espec ts; 13 clock gettime (ClOCK REALTIme, &ts); double aux ts. ty sec t ts, ty nsec 1000000000.0 4567 return aux -timeo sec 附录C测量时间◆9 //*米**水**米**米**米***米**木**米*米米**水*****水******米** 012 long hrclock_nsec o timespec ts 23 clock_gettime (CLOCK_REALTIME, &ts) long aux =ts tv_sec 1000000000+ ts tv_nsec return aux -timeo nsec 28//******米*****木*****米*********米********米***冰* int main o 31 timeo_nsec hrclocknsec o 34 time0_sec hrclock-sec o sleep (1) cout < hrclocknsec ( << endl cout < hrclocksec (<< endl return o C3Qt计时 Qt提供了一个 TIme类用于方便地完成事件计时。最常用的方法是 void QTime: start: / Set the time in the QTime object to the current time int QTime:: elapsed (: / Returns the number of milliseconds passed since the previous call to start of restart int QTime:: restart (:// Set the time in the QTime object to the t current time, and returns the elapsed time in milliseconds since t the previous call to start of restart o 使用 TIme类来进行计时相当地方便,如下面的例子所示: TIme t t start dosomething o printf( Time elapsed oi (ms)\n",t elapsed); C4 OpenMP计时 OpenMP提供了如下所示的计时函数 double omp_get-wtime( void 10◆多核与GPU编程:工具、方法及实践 这个函数会返回从“一个过去的特定时间点”到现在的时间差。 返回时间的精确度可从如下函数中得知 double omp_get_wick( void 如下面的代码所示,程序中代码片段的执行时间可以通过。mp_get_ wtime()函数两次返 回值的差值来估算: double timestart, timeend timestart =omp_get_wtime (; //do something timeEnd omp__wtime o cout < "Total time spent: "< timeEnd timestart < endT C5MPI计时 MPI提供了两个函数用于计时: MPI Wtime(当前时间)和 MPI Ticks。第一个函数读 取系统时钟;第二个函数返回系统时钟的分辨率(以秒为单位)。函数声明如下: double mpi_wtime( void double mpi wick( void MPI Wtime返回当前时间与之前一个特定时间点的时间差。因此,单次函数调用返回的 值没有任何意义,但是通过将函数两次返回值相减,即可获得时间差 double timestart, time end timestart= MPI_Wtime o //do something i meEnd MPI_Wtime( cout < Total time spent:<< time end - timestart < end l C.6CUDA计时 如6.7.7.1节所描述的,CUDA中的计时方法必然会与事件和流相关。CUDA内核的部 署是异步的,即,主机端调用 kernel函数后,可以直接返回,而不用等待GPU完成任务之 后再返回。主机端可以通过插入 cudaevent_t对象来完成GPU上事件的时间测量 代码清单C-2列出了如何用事件来对CUDA程序的执行时间进行测量的方法。 代码清单C-2如何通过事件来对CUDA程序进行时间测量的示例 2 cudastream t str 3 cudaevent t startt, endt float durat 6// initialize two events 7 cuda eventcreate (&startT) 8 cudaeventcreate (&endT)

...展开详情
立即下载 低至0.43元/次 身份认证VIP会员低至7折
抢沙发
一个资源只可评论一次,评论内容不能少于5个字
上传资源赚积分or赚钱
    最新推荐