[翻译]修复 TCriticalSection

注:基于本人英文水平,以下翻译只是我自己的理解,如对读者造成未知影响,一切后果自负。如果发现有翻译错误的,欢迎指正。

原文地址:https://www.delphitools.info/2011/11/30/fixing-tcriticalsection

TCriticalSection(TMonitor)有严重设计缺陷,在 进入/离开 不同的TCriticalSection 实例时可能结束你的线程, 甚至你的线程如果是序列化的,线程会结束执行。

(注:这段很绕,我理解就是说你有很多临界区时,可能会导致线程停止)

这是因为TCriticalSection实例是小的,动态分配的对象, 所以几个TCriticalSection实例可以放在同一个CPU cache line, 当这种行为发生时, 你会有很多缓存冲突在内核和线程之间。

这是有多严重? 好吧, 这取决于你的CPU有多少核,你有更多的核,就更容易产生。在一个4核CPU上,最坏的情况是导致200%的速度放慢,并且他不会重复(注:意思是随机发生的事件)

值得庆幸的是,有一个简单的解决方法,使用TFixedCriticalSection:

type

TFixedCriticalSection = class(TCriticalSection)

private

FDummy : array [0..95] of Byte;

end;

这可以确保实例的大小大于96字节,这意味着它会超过目前所有的CPU Cache line,所以没有了跨不同的临界区实例序列化。

作为奖励,它还使用了一个更大、更一致,FastMM bucket(桶),性能有大概7%提升。缺点是你使用了更多的内存,但是你真的有很多critical section(临界区)实例吗?

* (11-12-01): 提示,XE2中,TMonitor 的问题被修复了。

(没有说明TcriticalSection是否在XE2以后被修复了)

 

备注:

1: CPU cache line:(CPU缓存项?)这个我也不知道是什么,估计是CPU的缓存管理技术。

2:单核或临界区对象用得少的,估计遇到这种情况的机率很少。

3:低版本的Delphi还是建议修复一下。

4:为什么是96字节,我也不知道,这个已经到了CPU硬件范畴。

5:作者说 Class Helper不能解决这个问题。

6:作者说TRTLCriticalSection 也会有相似问题。

分享到:

3 条评论

沙发空缺中,还不快抢~