锁有以下特点:
而本文发现在改善锁的功耗的同时,往往会改善这个锁的吞吐率。
如何节省功耗:
Harware Techniques
clock gating:Deterministic Clock-Gating for Low-Power
Clock gating is a popular technique used in many synchronous circuits for reducing dynamic power dissipation. Clock gating saves power by adding more logic to a circuit to prune the clock tree. Pruning the clock disables portions of the circuitry so that the flip-flops in them do not have to switch states. Switching states consumes power. When not being switched, the switching power consumption goes to zero, and only leakage currents are incurred.
时钟门控(英语:Clock gating)是一种在同步时序逻辑电路的一种时间脉冲信号技术,可以降低芯片功耗。时钟门控通过在电路中增加额外的逻辑单元、优化时钟树结构来节省电能。
power gating:A Circuit Technique to Reduce Leakage in Deep-Submicron Cache Memories
Power gating is a technique used in integrated circuit design to reduce power consumption, by shutting off the current to blocks of the circuit that are not in use. In addition to reducing stand-by or leakage power, power gating has the benefit of enabling Iddq testing.
voltage and frequency scaling
Software Techniques
approximation
consolidation
energy-efficient data structures
fast active-to-idle switching
power-aware schedulers
energy-oriented compilers
本文观察了使用mutex锁与使用spinlock的功耗差别。
最终整个系统的功耗情况也不同。
可以看到看到mutex的功耗低,但能效低。spinlock在相同的情况有2倍的吞吐率。
所以选择一个适合的锁并不是那么简单的事情。
忙等确定会导致一定的能源损耗,降低能效。
这是由于一下原因导致的:
pause
指令往往会增加能源损耗…monitor/mwait
指令只有在内核态才能执行,而从用户态切换到内核态又有很大的overhead需要考虑。DVFS
策略,比较粗粒度,不容易使用。(反应比较慢,或许需要很久才能调整,而lock的变化又比较快)睡眠实际上可以节省很大一部分的能源损耗。
在Xeon机器上,max power consumption为206w,而如果是idle状态只有55w的能源损耗。所以如果在sleep状态的时候可以节省比较多的能源损耗。
但是睡眠往往又会降低能效。
主要问题在于将睡眠的线程唤醒需要7000个cycles,这一个overhead非常大。
传统的mutex锁很容易导致刚刚切换到睡眠状态的锁,又立刻将其唤醒,导致非常大的overhead。
本文主要贡献的锁,就是在这一点上做文章,设计了一个MUTEXEE。(具体思路?)
所以对于那些需要等待很久的锁,就将其切换到sleep状态。
在竞争程度比较高的时候,可以选择一部分锁进入睡眠等待,一部分锁active等待。但是对于谁需要等待很久,这就是一个unfair的问题了。进入sleep可以降低当前锁的竞争程度,在功耗与吞吐率上均有好处。
所以现在主要的trade off是吞吐率和锁等待延迟的trade off。
DVFS/monitor/mwait
or notTPP
是评价能耗的一个重要评判标准,Throughput Per Power 。EPO
即 Energy Per Operation 也是一个量化标准。Idele Power Consumption 均为上图为0个HT是的性能。两种策略均为55.5Watt。
当 activating 一个 socket 里面的第一个core的时候会比开这个socket剩下的core消耗的能源更多,这是因为新开一个socket也需要同时将uncore的一些components开起来。
新开一个sock分别在min和max中对应增加6.4与13.6。而开这个sock剩下的只需要2.3与5.6 Watss。
Memory的消耗功耗的变化范围没有Cores和Package变化大。
所以,总的来说,优化一个软件的能耗的机会在于
上图左边整体累计功耗。右边为CPI,为每一条指令平均需要的CPU周期数。
测试内容为等待一个永远也不会释放的锁。
所以,总的来说,sleeping会比spinning节省很多的能耗。
作者做了以下尝试:
对于local spinning这种CPI过低的,需要想方设法增高其CPI。而其CPI过低主要是乱序执行后,会导致每个cycle都会有一次memory load。(其实从理论上,还要确保增高CPI后,多的那些cycle不能又做一些高功耗的事情,不过应该增高所用的方法,都不会有很好的功耗)
Pause可以将CPI提高到4.6,但是其不仅不能降低功耗,还会增加功耗。(真的吗???Pause的实现方法??)
而真正增高其CPI同时降低其功耗,需要从避免过多的预测执行下手。可以使用memory barrier来达到这个效果。
左图中灰色的线可以节省最多达7%的功耗。(还是和sleeping 差别有点大啊)
所以本文后面的pause都用memory barrier来替代。
针对如何触发VF变化:需要在/sys/devices
写一个context file,需要去看下文章 The TURBO Diaries: Application-controlled Frequency Scaling Explained
VF的特点:
当到30个线程的时候,才更多可能一个物理核心上的线程都在空等,此时才会降低功耗。在线程少的时候并不明显。
MONITOR defines an address range used to monitor write-back stores. MWAIT is used to indicate that the software thread is waiting for a write-back store to the address range defined by the MONITOR instruction.
Intel manual
由于Monitor/mwait只能在kernel态使用,作者写了一个新的virtual device使得用户程序可以使用mwait等待一片内存区域。但是由于有用户态和内核态的切换,所以会有额外的开销。
(其实与sleeping相比,mwait更加高效吗?效率上提升有多少?单纯对比sleeping有多少优势?)
而使用Monitor/mwait主要有以下两个缺点:
在Busy waiting中作文章效果都不是特别理想
现有的节省能耗的方法只有sleeping比较有效。
目前sleeping是使用futex system call 实现的。
横轴为从睡眠到唤醒之间的间隔,纵轴为从唤醒到线程开始运行的整体时间。可以从图中发现,wake up call调用会有2k左右的latency,而被叫醒的线程大概还要另外的4k左右的cycles才能真正跑起来。
另外,所有的futex call都使用的同一个kernel lock,所以当需要futex sleep的线程多的时候,还会在kernel中产生contention,导致效率进一步降低。
所以在效率上,futex sleep的效率十分不尽人意。
当临界区的时间小于futex-sleep的延迟时,整体性能并不会有改善。(刚睡眠就被唤醒,sleep miss)
尝试通过降低公平性来提高futex sleep的performance
通过只让少数(2个)线程忙等,其他去睡眠,来提高效率。同时为了一定的公平性,在忙等一个时间T后,忙等的需要找一个线程来替换自己。T越大,公平性越差。
上图的ss-X代表着spin & sleep 在不同的busy-waiting和futex的比例X下的结果
这个结果就很有趣了。当X增大时,wake up的频率变低,此时busy waiting竞争的线程数也非常的少。(这个比例为什么会到1000这么大?????)最终吞吐率变高同时能耗也非常低,唯有此时的公平性不好。
mutex遇到的问题:
MUTEXEE针对
MUTEXEE还设置了不同模式应对不同场景,主要区别是在睡眠之前等多久和释放锁之后等多久。而场景是通过唤醒的比例来定的。
测试的结果和猜测的一致,在临界区的较短时,MUTEXEE在效率以及功耗上要大幅好于MUTEX。
而对于公平性测试:
95%的还是可以的,但是99%就会有很多由于睡眠太久导致不公平。
为了避免少数等待太久,可以设置timeout,timeout会大幅影响性能。
evaluate的是不带TO的MUTEXEE。可以看到在性能和能效上都有不错的表现与可扩展性。但是在thread比较多时,MUTEXEE拥有远超MUTEX的Tail latency(因为没有TO)。mcs lock在40个核的时候出现性能与功耗下坠,这是由于硬件线程数量限制。(所以说MUTEXEE设置的机制可以使其在线程数量大于HT时仍然保持一定的性能?????好像是这样的,如果竞争多的话,很多的都被放去睡眠了,不过从功能上来说,MUTEX也可以达到这个效果吧……)
在microbenchmark可以总结如下结论:
在现实世界测试集可以总结如下结论: