gpt4 book ai didi

Java CAS 操作比 C 等效操作执行得更快,为什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:23:23 24 4
gpt4 key购买 nike

  • 这里我有 Java 和 C 代码,它们尝试使用 CAS 执行原子增量操作。
  • 将一个 long 变量从 0 递增到 500,000,000。
  • C:耗时:7300 毫秒
  • Java:耗时:2083 毫秒
  • 任何人都可以仔细检查这些结果吗?因为我简直不敢相信他们。
  • 谢谢

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");
}

}

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);
}

运行.sh

#!/bin/bash

gcc -O3 test.c -o test.o
echo -e "\nC"
./test.o
javac SmallerCASTest.java
echo -e "\nJava"
java SmallerCASTest

其他细节:

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)

最佳答案

正如您所料,您正在比较苹果和橙子。 java 版本是真正的 CAS,失败时会重试,而 C 版本使用我在 java 中调用的 synchronized 形式。

参见 this question了解更多详情。

参见 this answer对于支持叙述的问题,它说 A full memory barrier is created when this function is invoked,即在 java 术语中,这是一个 synchronized 调用。

尝试使用 _compare_and_swap以同样的方式 AtomicLong 使用它的 java 等效项,即旋转函数直到值更改为您想要的值。

添加:

我找不到与 java AtomicLong 等效的明确 C++,但这并不意味着没有。本质上,AtomicLong 可以随时被任何线程更改,并且只有其中一个成功。但是,更改将是一致的,即更改将是一个或另一个线程更改的结果,而不是两者的组合。如果线程 A 尝试将值更改为 0xffff0000(或等效的 64 位数字),而线程 B 尝试更改为 0x0000ffff(同上),结果将是这两个值的任一个,更具体地说,它将 < strong>不是是 0x00000000 或 0xffffffff(当然除非涉及第三个线程)。

从本质上讲,AtomicLong 除此以外根本没有同步

关于Java CAS 操作比 C 等效操作执行得更快,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12799397/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com