【问题标题】:how to do an atomic copy of 128-bit number in gcc inline x86_64 asm?如何在 gcc 内联 x86_64 asm 中进行 128 位数字的原子复制?
【发布时间】:2010-12-16 20:47:44
【问题描述】:

我从上学(很久以前)就没有做过汇编,也从来没有做过任何 x86,但我在旧的现有代码中发现了一个令人讨厌的错误,即有人没有在他们应该做的地方进行原子操作。编写代码的人早已不在,这里没有人知道我的问题的答案。我需要做的是为 128 位值创建一个原子副本。我目前的代码如下:

void atomic_copy128(volatile void* dest,volatile const void* source) {
#if PLATFORM_BITS == 64
   #ifdef __INTEL_COMPILER 
      //For IA64 platform using intel compiler
      *((__int64*)source)=__load128((__int64*)dest,((__int64*)source)+1);
   #else 
      //For x86_64 compiled with gcc
      __asm__ __volatile__("lock ; movq  %0,%1"
           : "=r"(*((volatile long *)(source)))
           : "r"(*((volatile long *)(dest)))
           : "memory");
   #endif
#else
   #error "128 bit operations not supported on this platform."
#endif
}

这不是我最初尝试的代码,因为我在尝试让它编译和运行时已经搞砸了很多。当我将其设为完全无效的指令时,它不会编译。当我运行它时,它会一直执行,直到它到达这一行,然后生成“非法指令”错误消息。如有任何帮助,我将不胜感激。

【问题讨论】:

    标签: gcc atomic inline-assembly


    【解决方案1】:

    据我所知,“movq”最多支持一个内存操作数,并且它的参数无论如何都是 64 位大小的,所以即使支持两个内存操作数,它仍然不会给你那个原子 128-您正在寻找的位副本。

    【讨论】:

    • 感谢您的回复!我假设“movdqu”也最多只允许一个内存操作数?如果是这样,那么我真的有什么办法可以将它用于原子复制操作,因为我不能在一条指令中做到这一点,对吗?我在想这一切都错了吗?
    【解决方案2】:

    对于窗户:

    ::memset( dst, -1, 16 );
    _InterlockedCompareExchange128(source, -1, -1, dst );
    

    (但const必须删除)

    其他用途cmpxchg16b指令

    【讨论】:

      猜你喜欢
      • 2020-02-17
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 2018-09-18
      • 2010-12-31
      相关资源
      最近更新 更多