2011-03-23 15 views
7

Burada, compareAndSet (Java'da) kullanılarak kilitlenmeyen bir sıradan bazı kodlar vardır:Bu satırlar kilitlenmeyen bir sırada mı gerekli değil?

public void enq(T value) { 
    Node newNode = new Node(value); 
    while(true) { 
     Node last = tail.get(); 
     Node next = last.next.get(); 

     if(last != tail.get()) 
      continue; //???  

     if (next != null) { //improve tail 
      tail.compareAndSet(last, next); 
      continue; 
     } 

     if (last.next.compareAndSet(null, newNode)) { //update last node 
      tail.compareAndSet(last, newNode); //update tail 
      return; 
     } 
    } 
} 

public T deq() throws EmptyException { 
    while(true) { 
     Node first = head.get(); 
     Node last = tail.get(); 
     Node next = first.next.get(); 

     if(first != head.get()) 
      continue; //??? 

     if(first == last) { 
      if (next == null) 
       throw new EmptyException(); 

      tail.compareAndSet(last, next); 
      continue; 
     } 

     T value = next.value; 
     if (head.compareAnsdSet(first, next)) { 
      return value; 
     } 
    } 
} 

(kuyruk ve kuyruk kuyruğu üyeleridir)

Hem deq hemqq işlevinde, ilk kontrol benim için gereksiz görünüyor. ("???" ile yorum yaptılar) Sadece bir çeşit optimizasyon için var olduğundan şüpheleniyorum.

Burada bir şey mi eksik? Bu kontroller kodun doğruluğunu etkiler mi?

(Kod, kod eşdeğerini korurken daha az yuvalanmış ifs ve elseslere sahip olması için kod stilini yeniden düzenlemeye devam etsem de, "Çok İşlemcili Programlama Sanatından" alınmıştır)

+0

Yerel değişkenlerin tutarlı bir şekilde ayarlandığını kontrol ediyor gibi görünüyorlar, ancak kodun doğruluğunu etkileyip etkilemediklerini yanıtlamak için onu başkalarına bırakacağım. –

cevap

3

Evet, theíúvúth Yıllık Sempozyumu'na roceedingsof, bu IFS optimizasyonu gibi tek gerçek değere sahip ve bu kadar kinda büyük bir: CAS bellekten okunanlara göre inanılmaz derecede pahalıdır, bu nedenle bu sırada değerin değişmediğinden emin olmak ve böylece sonraki CAS üzerinde başarısız olma şansını azaltmak CAS-yeniden deneme sayısını azaltmaya yardımcı olur performansa yardımcı olur.

Ayrıca bir başka optimizasyon olarak, head.CAS içindeki son & & kuyruk güncelleme kontrol ilk == taşıyabilirsiniz: böylece kontrol, kuyruk kafa güncellendi yalnızca gerisinde ki yalnızca CAS başarılı oldu. Orada başka bir yere ihtiyacınız olmadığından, tail.get dosyasını da buraya taşıyabilirsiniz. Aşağıdaki örnek kod. Bu yardımcı olur umarım!

public T deq() throws EmptyException { 
while(true) { 
    Node first = head.get(); 
    Node next = first.next.get(); 

    if (first != head.get()) 
     continue; 

    if (next == null) { 
     throw new EmptyException(); 
    } 

    T value = next.value; 

    if (head.compareAndSet(first, next)) { 
     Node last = tail.get(); 

     if (first == last) { 
      tail.compareAndSet(last, next); 
     } 

     return value; 
    } 
} 

}

+0

Güzel, bir şey öğrendim. Teşekkürler. – Jaydee

2

Onlar gerekli değildir (kod eşdeğer tutarken kodu, daha az iç içe IFS olması kod stili planı ayrı gerçi, "Çok işlemcili Programlama Sanatı" alınıp birinin edilir), ancak performans nedenlerinden dolayı kullanıldığında, bir atomik işlem kullanılmadan kontrolün gerçekleştiğine dikkat edin. MSDN den

Örnek maliyetleri:

  • MemoryBarrier 20-90 döngü alarak ölçülmüştür.
  • InterlockedIncrement 36-90 döngü alarak ölçülmüştür.
  • Kritik bir bölümün elde edilmesi veya serbest bırakılması, 40-100 döngü alınarak ölçülmüştür. Bir muteksin elde edilmesi veya serbest bırakılması yaklaşık 750-2500 devir olarak ölçülmüştür. Bu söz konusu teknik için

Referans:

[Rudolph & Segall 84] Rudolph, L. ve Segall, Z. Dy-namik Merkezi olmayan Önbellek Şemaları paralel İşlemciler forMIMD. INVU Çöp derlemesi vardır düşünülürse, Com-bilgisayar Mimarisi Java sayfaları 340i> 347, 1984.

0

o bağlantılı liste algoritması olmayan engelleme var. JCP kitabında ayrıntılı bir açıklama bulunmaktadır (15.4.2.Bir Bağlantısız Bağlantılı Bağlantılı Liste

İlgili konular