2016-12-13 6 views
2

LongAdder의 작동 방식에 대한 질문이 아닙니다. 알아낼 수없는 흥미로운 구현 세부 사항입니다. 여기 LongAdder Striped64 wasUncontended 구현 세부 사항

이 Striped64에서 코드입니다 (나는 일부를 잘라 질문에 대한 관련 부품 떠 났어요) : 코드에서 많은 것들이이를 제외하고, 나에게 분명

final void longAccumulate(long x, LongBinaryOperator fn, 
          boolean wasUncontended) { 
    int h; 
    if ((h = getProbe()) == 0) { 
     ThreadLocalRandom.current(); // force initialization 
     h = getProbe(); 
     wasUncontended = true; 
    } 
    boolean collide = false; // True if last slot nonempty 
    for (;;) { 
     Cell[] as; Cell a; int n; long v; 
     if ((as = cells) != null && (n = as.length) > 0) { 
      if ((a = as[(n - 1) & h]) == null) { 
       //logic to insert the Cell in the array 
      } 
      // CAS already known to fail 
      else if (!wasUncontended) { 
       wasUncontended = true;  // Continue after rehash 
      } 
      else if (a.cas(v = a.value, ((fn == null) ? v + x : fn.applyAsLong(v, x)))){ 
       break; 
      } 

를 :

 // CAS already known to fail 
     else if (!wasUncontended) { 
      wasUncontended = true;  // Continue after rehash 
     } 

다음 CAS가 실패한다는 확실성은 어디에 있습니까? 이 검사는 하나의 사례에 대해서만 의미가 있습니다. 적어도 일부 스레드가 longAccumulate 메서드를 n 번째 시간 (n> 1)에 입력하고 사용중인 스핀이 첫 번째 사이클 인 경우 .

이 코드는 다음과 같이 말합니다 : 여러분 (일부 스레드)이 이전에 여기 있었고 특정 셀 슬롯에 경합이 있다면 CAS 값을 기존의 CAS 슬롯에 CAS하려고하지 마십시오. 조사.

나는 누군가를 위해 어떤 의미를 갖기를 희망합니다.

답변

3

그것은 실패 할 것이 아니라 실패한 것입니다. 이 메서드 호출은 LongAdderadd 메서드에 의해 수행됩니다.

public void add(long x) { 
    Cell[] as; long b, v; int m; Cell a; 
    if ((as = cells) != null || !casBase(b = base, b + x)) { 
     boolean uncontended = true; 
     if (as == null || (m = as.length - 1) < 0 || 
      (a = as[getProbe() & m]) == null || 
      !(uncontended = a.cas(v = a.value, v + x))) 
      longAccumulate(x, null, uncontended); 
    } 
} 
  1. 조건식의 제 1 세트는 긴 세포의 존재와 관련된다. 필요한 셀이 존재하지 않으면 필요한 셀을 원자 적으로 추가 한 다음 추가하여 추가하지 않으려 고하므로 계속적으로 누적을 시도합니다.
  2. 셀이 있으면 (v + x)을 추가하십시오. 추가 다음에 실패하면이 경우 왜 내 추측이

    wasUncontended = true;  // Continue after rehash 
    

    이다 있는가 그래서

을 낙관적/원자 축적 (성공까지 스핀)을 수행하려고, 경합 어떤 형태가 있었다 무거운 경합으로 실행중인 스레드가 따라 잡을 시간을 주려고하며 기존 셀을 다시 시도해야합니다.

+3

1) 어디서 왔는지 알고 있습니다. 2) 젠장! * CAS가 이미 실패한 것으로 알려진 *은 다음 CAS 작업이 실패한다는 것을 의미합니다. 이전 CAS 작업이 실패합니다. 나는 당신의 추측을 좋아한다. 아마도 코드에 대한 최적의 추가라고 증명할 수있는 테스트를했을 것이다. 귀하의 의견은 대단히 감사하겠습니다. – Eugene

+0

예, 나는 당신의 이론에 대해 99 % 확신하고 있습니다 (코드를 다시 본 후). 그것은 나에게 직관적이지만, 그 코드를 유지하는 사람에게는 인스턴스 감각을 줄 수 있습니다. 다시 한번 고맙습니다. 나는 이것을 받아 들일 것입니다. – Eugene

+0

그게 가장 현명한 설명입니다. 언젠가 CAS로 정수를 증가시키는 철저한 경쟁 루프를 시도하십시오. 과중한 경쟁으로 쉽게 90 % 실패한 CAS를 얻을 수 있습니다. – Voo