- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Microsoft 提供 InterlockedCompareExchange
用于执行原子比较和交换操作的函数。还有一个_InterlockedCompareExchange
内在。
在 x86 上,这些是使用 lock cmpxchg
指令实现的。
但是,通读这三种方法的文档后,他们似乎在对齐要求上并不一致。
英特尔的reference manual没有提及对齐(除了如果启用了对齐检查并且进行了未对齐的内存引用,则会生成异常)
我还查找了 lock
前缀,其中明确指出
The integrity of the LOCK prefix is not affected by the alignment of the memory field.
(强调我的)
所以英特尔似乎说对齐是无关紧要的。无论如何,该操作都是原子的。
_InterlockedCompareExchange
内部文档也没有提及对齐,但是 InterlockedCompareExchange
函数 指出
The parameters for this function must be aligned on a 32-bit boundary; otherwise, the function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems.
那么什么给出了呢?InterlockedCompareExchange 的对齐要求是否只是为了确保该函数即使在 cmpxchg
指令不可用的 486 之前的 CPU 上也能正常工作?根据上述信息,这似乎是可能的,但我想在依赖它之前确定一下。 :)
或者 ISA 是否需要对齐来保证原子性,而我只是在英特尔引用手册中查找了错误的位置?
最佳答案
x86 不要求将lock cmpxchg
指令对齐为原子指令。然而,为了获得良好的性能,对齐是必要的。
这应该不足为奇,向后兼容性意味着 14 年前使用手册编写的软件仍然可以在今天的处理器上运行。现代 CPU 甚至有一个专门用于分割锁检测的性能计数器,因为它非常昂贵。 (核心不能在操作期间仅保留对单个缓存行的独占访问;它必须执行类似于传统总线锁定的操作)。
微软究竟为何记录对齐要求尚不清楚。这对于支持 RISC 架构当然是必要的,但多处理器 x86 上的不可预测行为的具体声明甚至可能是无效的。 (除非它们意味着不可预测的性能,而不是正确性问题。)
您猜测仅适用于没有 lock cmpxchg
的 486 之前的系统可能是正确的;那里需要一种不同的机制,这可能需要某种围绕纯加载或纯存储的锁定。 (另请注意,486 cmpxchg
具有与 currently-undocumented opcode 不同的 modern cmpxchg
(0f b1
) (0f a7
),后者是 586 Pentium 中新增的;Windows 可能只使用 cmpxchg
在 P5 Pentium 及更高版本上,我不知道。)这也许可以解释某些 x86 上的奇怪现象,但并不意味着现代 x86 上的奇怪现象。
<小时/>Intel® 64 and IA-32 Architectures Software Developer’s Manual
Volume 3 (3A): System Programming Guide
January 20138.1.2.2 Software Controlled Bus Locking
To explicitly force the LOCK semantics, software can use the LOCK prefix with the following instructions when they are used to modify a memory location. [...]
• The exchange instructions (XADD, CMPXCHG, and CMPXCHG8B).
• The LOCK prefix is automatically assumed for XCHG instruction.
• [...][...] The integrity of a bus lock is not affected by the alignment of the memory field. The LOCK semantics are followed for as many bus cycles as necessary to update the entire operand. However, it is recommend that locked accesses be aligned on their natural boundaries for better system performance:
• Any boundary for an 8-bit access (locked or otherwise).
• 16-bit boundary for locked word accesses.
• 32-bit boundary for locked doubleword accesses.
• 64-bit boundary for locked quadword accesses.
有趣的事实:cmpxchg
without a lock
prefix is still atomic wrt. context switches ,因此可用于单核系统上的多线程。
即使未对齐,它仍然是原子的。中断(完全之前或完全之后),并且只有其他设备(例如 DMA)的内存读取才能看到撕裂。但此类访问也可以看到加载和存储之间的分离,因此即使旧 Windows 确实在单核系统上使用它来实现更高效的 InterlockedCompareExchange,它仍然不需要正确性对齐,只需要性能对齐。如果这可以用于硬件访问,Windows 可能不会这样做。
如果库函数需要执行与锁定 cmpxchg 分开的纯加载,这可能有意义,但不需要这样做。 (如果不内联,32 位版本必须从堆栈加载其参数,但这是私有(private)的,无法访问共享变量。)
关于winapi - 原子 x86 指令与 MS 的 InterlockedCompareExchange 文档的对齐要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1415256/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!