• 在这里,我有Java和C代码,它们试图使用CAS进行原子增量操作。
  • 将长变量从0增加到500,000,000。
  • C:花费时间:7300ms
  • Java:花费时间:2083ms
  • 可以再检查一次这些结果吗?因为我简直不敢相信他们。
  • 谢谢

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

    运行
    #!/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版本使用javasynchronized形式的调用时会失败,请重试。

    有关更多详细信息,请参见this question

    有关该问题的说明,请参见this answer,其中说A full memory barrier is created when this function is invoked,即用Java来讲,这是synchronized调用。

    尝试以与AtomicLong使用它的java等价方式相同的方式来使用_compare_and_swap,即旋转该函数,直到该值更改为所需的值为止。

    已添加:

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

    本质上,除此以外,AtomicLong的所有都没有没有同步。

    10-06 14:00
    查看更多