高性能计算导论课件第四PPT.ppt

高性能计算导论课件第四PPT.ppt

此“教育”领域文档为创作者个人分享资料,不作为权威性指导和指引,仅供参考
  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
高性能计算导论课件第四PPT

链表性能 100,000 ops/thread 80% Member 10% Insert 10% Delete 在多个线程的情况下,每个结点一个互斥量的实现仍然维持其低效性。与其他两个实现相比,过多的加锁和解锁使这个实现开销太大。 当Insert和Delete操作十分少时,读写锁远好于单互斥量实现。 另一方面,如果有相对多的Insert和Delete时(例如,大约每个10%),读写锁和单互斥量实现的性能几乎没有差别。 因此对链表操作来说,读写锁能够提供很大的性能提升,但只有在Insert和Delete操作十分少的时候才行。 缓存、缓存一致性和伪共享 回想一下,芯片设计人员已经为处理器增加了相对快速的内存——缓存。 缓存的设计考虑了时间和空间局部性原理:如果一个处理器在时间t访问内存位置x,那么很可能它在一个接近t的时间访问接近x的内存位置。如果一个处理器需要访问主存位置x,那么就不只是将x的内容传入(出)主存,而是将一块包含x的内存块传入(出)主存。我们将这样一块内存称为缓存行或者缓存块。 缓存一致性 假设x是一个共享变量,值为5,线程0和1将x从内存读入它们各自的缓存,因为它们都想要执行语句: my_y=x; 这里,my_y是一个被两个线程定义的私有变量。现在假设线程0执行语句: x++: 最后,假设线程1正在执行: my_z =x; my_z是另一个私有变量。 请问,my_z的值是多少呢?是5吗?或者是6吗? 缓存一致性 问题在于:x(至少)有3个副本,一个在主存中,一个在线程0的缓存中,一个在线程1的缓存中。当线程0执行x++时,主存和线程1缓 存中的值会发生什么变化?这是缓存一致性问题,我们在第2章讨论过。 大部分系统实现会让缓存感知到它缓存的数据有否变化。在线程0执行x++后,线程1中x的缓存行将被标记为无效,在赋值my_z=x前,运行线程1的核就能看到它所存储的x的副本已经过期了。这样,运行线程0的核不得不更新x在主存中的副本,然后运行线程1的核再从主存得到x的更新值。 缓存一致性的影响 缓存一致性可能会对共享内存系统的性能有巨大的影响。 为了说明这一点,我们再来看看Pthreads矩阵一向量乘法的例子 Pthreads矩阵-向量乘法程序 矩阵-向量乘法的运行时间和效率 如果只考虑算术运算,可以预测到:采用单线程来计算这3种输入所花费的时间相差不多。 然而,很明显地,情况并不是这样。单线程运行时,8 000 000 x8的系统比8000×8000的系统需要多14%的时间,8x8 000 000的系统比8000×8000的系统需耍多28%的时间。这个差别部分归因于缓存的性能。 线程安全性 Thread-Safety 线程安全性 如果一个代码块能够被多个线程同时执行而不引起问题,那么它是线程安全的 例子 假设要使用多线程来对一个文件进行‘分词’。 文件由普通的英语文本构成,要分析出的是被空格、tab和换行符分隔的连续的字符序列。 简单的方法 将输入文件分成行,把每一行按顺序分给线程 即,第一行给线程0,第二行给线程1,…,第t行给线程t-1,第t+1行给线程0,以此类推。 简单的方法 我们可以通过使用信号量将访问输入行串行化 在一个线程读了一行输入后,他就能够对这一行进行分词,使用string.h中的strtok函数 strtok函数 在第一次调用它时,string参数应该是要被分词的文本,在我们的例子中就是一行输入 后面调用它时, string参数应该是NULL strtok函数 在第一次调用时,strtok缓存一个指向string的指针,在接下来连续的调用中,strtok返回从缓存的副本中分隔出的连续的词。 多线程分词器的第一个版本的程序(1) 多线程分词器的第一个版本的程序(2) 主线程初始化一个有t个信号量的数组(每个线程一个)。线程0的信号量初始化为1,所有其他的信号量初始化为0. 第9~11行的代码强制线程按顺序访问输入行。线程首先读人第一行,此时所有其他的线程阻塞在sem_wait上。当线程0执行sem_post时,线程1能读一行输入。 在每个线程已经读了它的第一行输入后(或已经达到文件尾),更多额外的输入会在第24~26行读人 fgets函数用于读一行输入,而f第15~22行用于识别这一行的词。 用一个线程运行 它能正确地对输入进行分词 Pease porridge hot. Pease porridge cold. Pease porridge in the pot Nine days old. 用两个线程运行 Oops! 这是怎么回事? 再回头看一下strtok如何对输入行进行缓存。它通过声明一个sto

文档评论(0)

130****9768 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档