我知道如何在x86 ASM中自动写入值。但我怎么读一个? LOCK前缀不能与mov。
一起使用为了增加价值,我正在做:
lock inc dword ptr Counter
如何以线程安全的方式读取计数器?
答案 0 :(得分:5)
我在this帖子中向您解释:
访问可缓存的内存 分割总线宽度,缓存线, 和页面边界不保证 英特尔酷睿2双核处理器, Intel Core Duo,Pentium M,Pentium 4, Intel Xeon,P6系列,Pentium和 Intel486处理器。英特尔酷睿2 Duo,Intel Core Duo,Pentium M, Pentium 4,Intel Xeon和P6系列 处理器提供总线控制信号 允许外部存储器子系统 使拆分访问成为原子; 但是,非对齐数据访问将会 严重影响了业绩 处理器,应该避免。
所以使用:
LOCK CMPXCHG EAX, [J]
LOCK CMPXCHG第一个围栏缓存内存,并将EAX与目标值进行比较,如果目标值不相等则则EAX中的结果为目标值。
编辑: 链接到:
Intel® 64 and IA-32 Architectures Software Developer’s Manuals
在Volume 3A: System Programming Guide检查第8.1.1节
中同时检查:Optimization Reference Manual section: CHAPTER 7 OPTIMIZING CACHE USAGE
答案 1 :(得分:4)
我不是汇编专家,但字大小(在x86,32位上)读/写应该是原子的。
你需要锁定增量的原因是因为它既是读也是写。
答案 2 :(得分:1)
对于简单的阅读,它主要是关于对齐。确保原子读取的最简单方法是始终使用“自然”对齐 - 即,对齐至少与项目的大小一样大(例如,32位项目是32位对齐)。
未对齐的读取不一定是原子的。举一个极端的例子,考虑在奇数地址读取32位值,其中第一个字节在一个高速缓存行中,其他三个字节在另一个高速缓存行中。在这种情况下,原子读取基本上是不可能的。
由于(至少大多数)处理器使用64位宽的内存总线,因此希望以原子方式读取的最大项是64位。
答案 3 :(得分:1)
阅读其他回复很有意思。我认为@GJ可能就是钱。
多年来,32位读写始终是原子的。只是在最近几年才真正积极的缓存,这已不再保证。
我想这就是为什么我更喜欢C ++,Java或者我和机器代码之间的一些东西。这些天机器代码太复杂而无法可靠地编写(除非你 很多 以保持你的技能敏锐)。幸运的是,今天的优化编译器非常好,您很少需要手动优化的汇编程序的性能。