gpt4 book ai didi

c++ - WORD 的 cmpxchg 比 BYTE 快

转载 作者:可可西里 更新时间:2023-11-01 18:38:41 30 4
gpt4 key购买 nike

昨天我发布了this question关于如何编写快速自旋锁。感谢 Cory Nelson,我似乎找到了一种优于我问题中讨论的其他方法的方法。我使用 CMPXCHG 指令来检查锁是否为 0 从而释放。 CMPXCHG 对“BYTE”、WORDDWORD 进行操作。我假设该指令在 BYTE 上运行得更快。但是我写了一个实现每种数据类型的锁:

inline void spin_lock_8(char* lck)
{
__asm
{
mov ebx, lck ;move lck pointer into ebx
xor cl, cl ;set CL to 0
inc cl ;increment CL to 1
pause ;
spin_loop:
xor al, al ;set AL to 0
lock cmpxchg byte ptr [ebx], cl ;compare AL to CL. If equal ZF is set and CL is loaded into address pointed to by ebx
jnz spin_loop ;jump to spin_loop if ZF
}
}
inline void spin_lock_16(short* lck)
{
__asm
{
mov ebx, lck
xor cx, cx
inc cx
pause
spin_loop:
xor ax, ax
lock cmpxchg word ptr [ebx], cx
jnz spin_loop
}
}
inline void spin_lock_32(int* lck)
{
__asm
{
mov ebx, lck
xor ecx, ecx
inc ecx
pause
spin_loop:
xor eax, eax
lock cmpxchg dword ptr [ebx], ecx
jnz spin_loop
}
}
inline spin_unlock(<anyType>* lck)
{
__asm
{
mov ebx, lck
mov <byte/word/dword> ptr [ebx], 0
}
}

然后使用以下伪代码测试锁(请注意 lcm 指针始终指向可被 4 整除的地址):

<int/short/char>* lck;
threadFunc()
{
loop 10,000,000 times
{
spin_lock_8/16/32 (lck);
spin_unlock(lck);
}
}
main()
{
lck = (char/short/int*)_aligned_malloc(4, 4);//Ensures memory alignment
start 1 thread running threadFunc and measure time;
start 2 threads running threadFunc and measure time;
start 4 threads running threadFunc and measure time;
_aligned_free(lck);
}

我在具有 2 个物理内核并能够运行 4 个线程的处理器 (Ivy Bridge) 上获得了以毫秒为单位测量的以下结果。

           1 thread    2 threads     4 threads
8-bit 200 700 3200
16-bit 200 500 1400
32-bit 200 900 3400

数据表明所有功能的执行时间相同。但是当多个线程必须检查是否 lck == 0 时,使用 16 位可以明显更快。这是为什么?我不认为它与 lck 的对齐有关?

提前致谢。

最佳答案

据我所知,锁作用于一个字(2 个字节)。它在 486 中首次引入时就是这样写的。

如果你在不同的大小上携带一个锁,它实际上生成了 2 个锁的等价物(双字的锁字 A 和字 B)。对于一个字节,它可能必须阻止第二个字节的锁定,这有点类似于2把锁...

因此您的结果符合 CPU 优化。

关于c++ - WORD 的 cmpxchg 比 BYTE 快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11977749/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com