【发布时间】:2013-09-21 15:28:37
【问题描述】:
我正在处理一个需要双宽度比较和交换操作 (cmpxchg16b) 的项目。我通过luke h 找到了以下代码,但是当我使用“g++-4.7 -g -DDEBUG=1 -std=c++0x dwcas2.c -o dwcas2.o”编译它时,出现以下错误:
错误:
g++-4.7 -g -DDEBUG=1 -m64 -std=c++0x dwcas2.c -o dwcas2.o
dwcas2.c: Assembler messages:
dwcas2.c:29: Error: junk `ptr ' after expression
任何想法为什么?,我觉得它是一个小而容易修复的东西,我只是看不到它。
电脑规格: 运行 Ubuntu 12.04 LTS 的 64 核 ThinkMate RAX QS5-4410 服务器。它是一个 NUMA 系统,具有四个 AMD Opteron 6272 CPU(每个芯片 16 个内核 @2.1 GHz)和 314 GB 共享内存。
代码:
#include <stdint.h>
namespace types
{
struct uint128_t
{
uint64_t lo;
uint64_t hi;
}
__attribute__ (( __aligned__( 16 ) ));
}
template< class T > inline bool cas( volatile T * src, T cmp, T with );
template<> inline bool cas( volatile types::uint128_t * src, types::uint128_t cmp, types::uint128_t with )
{
bool result;
__asm__ __volatile__
(
"lock cmpxchg16b oword ptr %1\n\t"
"setz %0"
: "=q" ( result )
, "+m" ( *src )
, "+d" ( cmp.hi )
, "+a" ( cmp.lo )
: "c" ( with.hi )
, "b" ( with.lo )
: "cc"
);
return result;
}
int main()
{
using namespace types;
uint128_t test = { 0xdecafbad, 0xfeedbeef };
uint128_t cmp = test;
uint128_t with = { 0x55555555, 0xaaaaaaaa };
return ! cas( & test, cmp, with );
}
【问题讨论】:
-
应该只是
lock cmpxchg16b %1。在这种情况下,不需要大小,因为指令cmpxchg16b暗示了它。无论您在哪里获得此代码,似乎都是由认为内联汇编程序等同于 MASM 的人编写的。 -
我可以为不使用内联汇编做一个宣传吗?使用__sync_bool_compare_and_swap 怎么样?甚至可能是 std::atomic?
-
@DavidWohlferd 哦,现在来吧,内在函数太简单了,但话说回来,您可能希望您在 GCC 上的 wiki 条目能够发挥作用;-)
-
我偶然发现了另一个问题/答案,这似乎是此代码的起源。 stackoverflow.com/questions/4825400/cmpxchg16b-correct
-
@MichaelPetch - 嘿,我为那个 wiki 条目出汗。当然,你和我可能是唯一读过它的人,但仍然...... Re 4825400:在接受的答案中也没有内存破坏。虽然我看到您添加了评论,但您没有提及。值得为这个 5 岁以上的问题争论不休吗?
标签: c++ inline-assembly