什么(如果有的话)是x86 asm xchg指令的C#等价物?
有了这个命令,哪个imo是一个真正的交换(不像Interlocked.Exchange),我可以简单地自动交换两个int,这就是我真正想做的事情.
更新:
示例代码基于我的建议.变量后缀"_V"被装饰为volatile:
// PART 3 - process links
// prepare the new Producer
address.ProducerNew.WorkMask_V = 0;
// copy the current LinkMask
address.ProducerNew.LinkMask_V = address.Producer.LinkMask_V;
// has another (any) thread indicated it dropped its message link from this thread?
if (this.routerEmptyMask[address.ID] != 0)
{
// allow all other bits to remain on (i.e. turn off now defunct links)
address.ProducerNew.LinkMask_V &= ~this.routerEmptyMask[address.ID];
// reset
this.routerEmptyMask[address.ID] = 0;
}
// PART 4 - swap
address.ProducerNew = …Run Code Online (Sandbox Code Playgroud) 我正在用c ++编写多线程应用程序,其中性能至关重要.我需要在线程之间复制小结构时使用大量锁定,为此我选择使用自旋锁.
我已经做了一些研究和速度测试,我发现大多数实现大致同样快:
__asm {}使用类似这样的代码,它得分约70个时间单位,但我不确定是否已创建适当的内存屏障.编辑:这里给出的时间是2个线程锁定和解锁螺旋锁1,000,000次所需的时间.
我知道这并没有太大的区别,但是由于自旋锁是一个使用频繁的对象,人们会认为程序员会同意以最快的方式制作自旋锁.谷歌搜索导致许多不同的方法.我认为如果使用内联汇编并使用指令而不是比较32位寄存器来实现上述方法将是最快的CMPXCHG8B.此外,必须考虑内存障碍,这可以通过LOCK CMPXHG8B(我认为?)来完成,这保证了内核之间共享内存的"专有权".最后[有人建议]对于繁忙的等待应该伴随NOP:REP,这将使超线程处理器切换到另一个线程,但我不确定这是否是真的?
根据我对不同螺旋锁的性能测试,可以看出没有太大区别,但出于纯粹的学术目的,我想知道哪一个是最快的.但是由于我在汇编语言和内存障碍方面的经验非常有限,如果有人可以为我在LOCK CMPXCHG8B中提供的最后一个示例编写汇编代码并在以下模板中使用适当的内存屏障,我会很高兴:
__asm
{
spin_lock:
;locking code.
spin_unlock:
;unlocking code.
}
Run Code Online (Sandbox Code Playgroud) 在大多数情况下,我写了一些无锁代码,可以在本地读取时正常工作.
本地旋转读取内存是否必然意味着我必须在旋转读取之前始终插入内存屏障?
(为了验证这一点,我设法生成一个读写器组合,导致读者永远不会看到写入的值,在某些非常特定的条件下 - 专用CPU,连接到CPU的进程,优化器一直向上,没有其他工作在循环中完成 - 所以箭头指向那个方向,但我不完全确定旋转内存屏障的成本.)
如果在缓存的存储缓冲区中没有任何内容被刷新,那么旋转内存屏障的成本是多少?即,所有过程都在做(在C中)
while ( 1 ) {
__sync_synchronize();
v = value;
if ( v != 0 ) {
... something ...
}
}
Run Code Online (Sandbox Code Playgroud)
我是否正确地假设它是免费的并且它不会阻碍任何流量的内存总线?
另一种方法是问:内存屏障是否会执行任何操作:刷新存储缓冲区,对其应用失效,并阻止编译器在其位置重新排序读/写?
反汇编,__ sync_synchronize()似乎转化为:
lock orl
Run Code Online (Sandbox Code Playgroud)
从英特尔手册(同样模糊的新手):
Volume 3A: System Programming Guide, Part 1 -- 8.1.2
Bus Locking
Intel 64 and IA-32 processors provide a LOCK# signal that
is asserted automatically during certain critical memory
operations to lock the system bus or equivalent link.
While this output signal is asserted, requests …Run Code Online (Sandbox Code Playgroud) 好吧,我有一个关于线程的问题.
有两个未同步的线程同时运行并使用全局资源"int num"1st:
void Thread()
{
int i;
for ( i=0 ; i < 100000000; i++ )
{
num++;
num--;
}
}
Run Code Online (Sandbox Code Playgroud)
第二:
void Thread2()
{
int j;
for ( j=0 ; j < 100000000; j++ )
{
num++;
num--;
}
}
Run Code Online (Sandbox Code Playgroud)
问题陈述:程序结束时变量"num"的可能值是什么.现在我会说0将是程序结束时num的值,但是,尝试运行此代码,你会发现结果是随机的,我不明白为什么?
完整代码:
#include <windows.h>
#include <process.h>
#include <stdio.h>
int static num=0;
void Thread()
{
int i;
for ( i=0 ; i < 100000000; i++ )
{
num++;
num--;
}
}
void Thread2()
{
int j;
for ( j=0 …Run Code Online (Sandbox Code Playgroud) 我是低级别的新手,所以我完全忘记了你可能面临的问题,我甚至不确定我是否理解"原子"一词.现在我试图通过扩展程序集围绕内存操作进行简单的原子锁.为什么?为了好奇.我知道我在这里重新发明轮子,可能会过度简化整个过程.
这个问题? 我在这里提供的代码是否实现了使内存操作既线程安全又可重入的目标?
我只想做...
代码:
volatile int atomic_gate_memory = 0;
static inline void atomic_open(volatile int *gate)
{
asm volatile (
"wait:\n"
"cmp %[lock], %[gate]\n"
"je wait\n"
"mov %[lock], %[gate]\n"
: [gate] "=m" (*gate)
: [lock] "r" (1)
);
}
static inline void atomic_close(volatile int *gate)
{
asm volatile (
"mov %[lock], %[gate]\n"
: [gate] "=m" (*gate)
: [lock] "r" (0)
);
}
Run Code Online (Sandbox Code Playgroud)
然后像:
void *_malloc(size_t size)
{
atomic_open(&atomic_gate_memory);
void *mem = malloc(size);
atomic_close(&atomic_gate_memory); …Run Code Online (Sandbox Code Playgroud)