4 Multiprocessors and Thread-Level Parallelism
松仓 (顽虫)
- 章节名:4 Multiprocessors and Thread-Level Parallelism
一直对多处理器结构一些基本概念和机制认知有些模糊,这阵子终于抽空看了《量化》的相关章节,清晰许多。画了张[脑图](http://www.xmind.net/share/zwxiao/multiprocessors-and-cache-coherence/),总结了多处理器和缓存一致性的基本问题。 --- 书里提到一个常见的认识误区,也是我平时容易忽视的: **用执行速度是否线性提高来衡量多处理器的性能**
我们经常用同一段代码来比较不同系统的性能,但其实这是不公平的。因为并行版本的程序在单处理器上可能比串行版本要慢得多,相当于你让单处理器去做它不擅长的事情。**公平的做法应该是比较各个处理器上各自最优的版本**。但其实这样子则会带来算法差异的问题,因为并行版本往往采用针对并行优化过的算法,这样就是拿苹果和橙子比较了。为了区分这两种情况,作者提出相对加速比(relative speedup,用同样的程序测试出来的加速比)和真实加速比(true speedup,分别用各个处理器上最优的程序测试出来的加速比)这两个概念。 另一方面,作者说以是否线性提高来衡量多处理器**性能**也是不对;不过我觉得作者这一点多虑了。其实我们一般是拿线性提高来衡量系统的**伸缩性**,这是没有问题的。但是单纯的看核数/处理器数的增加也是不公平的,比如肇国吴总他们当年测[COREMU](http://sourceforge.net/p/coremu)时,就遇到过超线性加速的情况;这是由于当核数增多时,可用的Cashe也变大,提高了缓存命中率从而带来更好的性能。所以在评测中需要综合考虑Cache,I/O等子系统带来的影响。 比较两个处理器之间的加速比并不总能反映它们的相对性能。执行时间变化趋势图可以看,但是要小心别被误导。 另外[这篇文章](http://gernot-heiser.org/benchmarking-crimes.html)也总结了很多常见的评测和分析的误区,值得一读。 --- #### 原子指令 还有以前傻傻的老搞不清楚为什么要用exchange这样的指令作为最基本的原子指令,为什么不实现一个锁呢?看书的时候顺便才想明白,其实我们拿锁的过程就是读取和写入锁状态两个动作,一读一写正好就是exchange的语义。由于硬件本身只能实现单独一个读或写操作的原子性,原子指令就是为了解决读写两个动作的原子性这个问题而引入的。 书上介绍的是用特殊的读指令load linked(LL)和写指令store conditional(SC)来实现原子操作。先用LL读取某个地址,在SC要写入值之前,会先检查LL所指向的内存值是否发生改变,是的话则操作失败。这样这一对指令合起来就能实现原子的exchange操作。书里没说LL/SC是怎么实现的,扫了Intel的文档也没看到相关介绍,我猜测应该是这样:LL相当于注册了一个内存监听器,以后执行写操作时,会先检查内存地址是否被LL注册,是的话则置上某个flag;当SC执行时先独占bus,保证没有其他写操作进行,然后检查该flag是否被置上,是的话说明指定的内存被改过了,操作失败,反之则操作成功。 http://xoyo.name/2012/02/multiprocessors-and-cache-coherence/
说明 · · · · · ·
表示其中内容是对原文的摘抄