Jig*_*gar 7 c java concurrency compare-and-swap
Java代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class SmallerCASTest {
public static void main(String[] args){
final long MAX = 500l * 1000l * 1000l;
final AtomicLong counter = new AtomicLong(0);
long start = System.nanoTime();
while (true) {
if (counter.incrementAndGet() >= MAX) {
break;
}
}
long casTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
System.out.println("Time Taken=" + casTime + "ms");
}
}
Run Code Online (Sandbox Code Playgroud)
C代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NITER 500000000
int main (){
long val = 0;
clock_t starttime = clock ();
while (val < NITER){
while (1){
long current = val;
long next = current+1;
if ( __sync_bool_compare_and_swap (&val, current, next))
break;
}
}
clock_t castime = (clock()-starttime)/ (CLOCKS_PER_SEC / 1000);
printf ("Time taken : %d ",castime);
}
Run Code Online (Sandbox Code Playgroud)
run.sh
#!/bin/bash
gcc -O3 test.c -o test.o
echo -e "\nC"
./test.o
javac SmallerCASTest.java
echo -e "\nJava"
java SmallerCASTest
Run Code Online (Sandbox Code Playgroud)
其他详情:
System : Linux XXXXXXXXX #1 SMP Thu Mar 22 08:00:08 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
gcc --version:
gcc (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)
java -version:
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)
Run Code Online (Sandbox Code Playgroud)
你正在比较苹果和橘子,我相信你的预期.该java版本是一个真正的CAS与失败重试,而C版本使用什么我在调用java一个synchronized形式.
有关详细信息,请参阅此问题.
请参阅该问题的答案,以支持其所说的叙述A full memory barrier is created when this function is invoked,即在java术语中,这是一个synchronized电话.
尝试使用_compare_and_swap以相同的方式AtomicLong使用其java等价物,即旋转函数,直到值更改为您想要的值.
添加:
我找不到一个确切的C++等价的java,AtomicLong但这并不意味着没有一个.从本质上讲,AtomicLong任何时候都可以通过任何线程更改,只有其中一个成功.但是,更改将是一致的,即更改将是由一个或另一个线程更改的结果,它不会是两者的组合.如果线程A尝试将值更改为0xffff0000(或等效的64位数),而线程B尝试更改为0x0000ffff(同上),则结果将是两个值中的任何一个,更具体地说,它将不是 0x00000000或0xffffffff(除非是当然第三个线程涉及).
本质上,AtomicLong具有完全没有同步这以外.
编辑确实,正如您所指出的,java似乎使用CAS操作来实现incrementAndGet。
我的测试似乎表明 C 和 Java 版本具有大致相同的性能(这是有道理的,因为耗时的部分是原子的,而不是 java 或 C 编译器设法完成的其余部分的任何优化)。
所以在我的机器(Xeon X3450)上,java版本需要~4700 ms,C版本~4600 ms,使用__sync_add_and_fetch()的C版本~3800 ms(这表明java可以在这里改进,而不是在上面实现所有原子操作) CAS 顶部)。
java版本是
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.10.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Run Code Online (Sandbox Code Playgroud)
GCC 是 4.4.3,x86_64。
操作系统是 Ubuntu 10.04 x86_64。
所以我只能得出结论,你的测试中有些东西似乎很可疑。