64位比较和交换(CAS)应该在32位机器上工作吗? (或64位机器?) [英] Should 64bit Compare&Swap (CAS) work on a 32bit machine? (or 64bit machine?)

查看:206
本文介绍了64位比较和交换(CAS)应该在32位机器上工作吗? (或64位机器?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在32位机器上读到,可以使用对齐的64位块的 CAS 操作。
类似地,在64位机器中,可以使用对齐的128位块的 CAS 操作。



我使用的是32位机器,所以我尝试了以下方法:

pre $ // sizeof(long long)是8个字节,所以64位
long long y = 12;
long long z = 12;
long long x = 99;
__sync_bool_compare_and_swap(& y,z,x);

CAS 成功更改 y 99



一个 char数组[8]; (大小为64位)而不是 long long 。我做的是:

  char full [8] = {'0','1','2','3' ,'4','5','6','7'}; 
char full2 [8] = {'0','1','2','3','4','5','6','7'};
char full3 [8] = {'5','8','9','G','X','5','6','U'};
__sync_bool_compare_and_swap(full,full2,full3);

但是在这种情况下, CAS 失败尽管完整 full2 具有完全相同的数据。 (我还检查了完整 full2 哪里正确地被分配了)



因此,第一次看来, CAS 可以用于64位,但第二次看起来不行。任何想法为什么?

编辑



(64位机器怎么样?)



好的,所以问题在于我在 CAS中使用 char * code>这些只被检查。所以解决方案是转换为 long long 或者转换为64位值的 uint64_t



但是当我需要使用128位的值时,我应该怎样处理64位机器? long long 在64位机器中仍然是64位,并且 c> uint128_t 似乎不存在于C中。我应该使用哪种类型? double long 在我的64位机器中似乎是128位,但是在执行以下操作时:

  double long y = 32432143243214; 
double long z = 32432143243214;

int x = __sync_bool_compare_and_swap(& y,z,1234321990);

我得到这个编译错误
错误:参数的不兼容类型1'__sync_bool_compare_and_swap'

解决方案

看起来你忘记了deref你的指针并投射。 / p>

我测试过这是唯一正确的组合:

  __sync_bool_compare_and_swap((long long *)full,*(long long *)full2,*(long long *)full3); 

您需要转换第一个参数,否则它只会交换第一个字符。



关于处理128位双倍长,这是来自gcc 4.1.2 docs


英特尔文档中给出的定义仅允许对于
使用类型int,long,long long以及它们的未签名
对应项。
GCC将允许任何整数标量或指针类型为1,2,4或
8个字节。



所以看来你不能用这个函数来处理这种情况。


So I read that in a 32bit machine, one can use the CAS operation with aligned 64bit blocks. Similarly, in a 64bit machine, one can use the CAS operation with aligned 128bit blocks.

I'm using a 32bit machine so I tried the following:

// sizeof(long long) is 8 bytes, so 64 bits
long long y = 12;
long long z = 12;
long long x = 99;
__sync_bool_compare_and_swap(&y, z, x);

and the CAS succeeded changing the value of y to 99.

But then I tried using a char array[8];(which size is 64 bits) instead of a long long. And I do:

char full[8] = {'0', '1', '2', '3', '4', '5', '6', '7'}; 
char full2[8] = {'0', '1', '2', '3', '4', '5', '6', '7'};   
char full3[8] = {'5', '8', '9', 'G', 'X', '5', '6', 'U'};
__sync_bool_compare_and_swap(full, full2, full3);  

But in this case, the CAS fails although full and full2 have exactly the same data. (I also checked that full and full2 where correctly alligned)

So the first time it seems that a CAS can be used to 64bit, but the second time it seems it can't. Any ideas why?

EDIT

(How about 64bit machines?)

Ok, so the problem was that I was using char * in my CAS and these were only checked. So the solution was to cast to long long or to uint64_t which are 64bit values.

But what should I do with a 64bit machine when I need to use 128bit value? long long is still 64bit in a 64bit machine and uint128_t doesn't seem to exist in C. So to which type should I cast? double long seems to be 128bit in my 64bit machine, but when doing the following:

  double long y = 32432143243214;
  double long z = 32432143243214;

  int x = __sync_bool_compare_and_swap(&y, z, 1234321990);

I get this compile error error: incompatible type for argument 1 of ‘__sync_bool_compare_and_swap’.

解决方案

Looks like you forgot to deref your pointers and cast.

I tested and this is the only combination that is correct:

__sync_bool_compare_and_swap((long long*)full, *(long long *)full2, *(long long *)full3);

You need to cast the first param or it will only swap the first char.

Regarding handling 128-bit double long, this is from the gcc 4.1.2 docs.

The definition given in the Intel documentation allows only for the use of the types int, long, long long as well as their unsigned counterparts. GCC will allow any integral scalar or pointer type that is 1, 2, 4 or 8 bytes in length.

So it would seem you cannot use this function to handle that case.

这篇关于64位比较和交换(CAS)应该在32位机器上工作吗? (或64位机器?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆