OpenMP'de atomik ve kritik arasındaki fark nedir?


Yanıtlar:


173

G_qCount üzerindeki etki aynıdır, ancak yapılan farklıdır.

Bir OpenMP kritik bölümü tamamen geneldir - herhangi bir rastgele kod bloğunu çevreleyebilir. Bununla birlikte, bir iş parçacığı kritik bölüme her girdiğinde ve çıktığında (serileştirmenin doğal maliyetine ek olarak) önemli bir ek yüke neden olarak bu genellik için ödeme yaparsınız.

(Ek olarak, OpenMP'de tüm adlandırılmamış kritik bölümler aynı kabul edilir (tercih ederseniz, tüm adlandırılmamış kritik bölümler için yalnızca bir kilit vardır), böylece bir iş parçacığı yukarıdaki gibi [adsız] bir kritik bölümdeyse, hiçbir iş parçacığı girilemez. [isimsiz] kritik bölüm Tahmin edebileceğiniz gibi, adlandırılmış kritik bölümleri kullanarak bu sorunu aşabilirsiniz).

Atomik bir operasyon çok daha düşük ek yüke sahiptir. Mümkün olduğunda, (diyelim ki) bir atomik artış işlemi sağlayan donanımdan yararlanır; bu durumda kod satırına girerken / çıkarken kilit / kilit açma gerekmez, sadece donanımın size müdahale edilemeyeceğini söylediği atomik artışı yapar.

Artıları, ek yükün çok daha düşük olması ve atomik bir işlemde olan bir iş parçacığının gerçekleşmek üzere olan (farklı) atomik işlemleri engellememesidir. Olumsuz tarafı, atomiklerin desteklediği kısıtlı işlemler dizisidir.

Elbette, her iki durumda da, serileştirme maliyetini üstlenirsiniz.


5
"taşınabilirliği kaybedebilirsiniz" - Bunun doğru olduğundan emin değilim. Standart (sürüm 2.0) atomik hareketine izin verilmez belirtir (temelde gibi şeyler ++ve *=) ve donanım desteklemediği durumda, bunlar yerine olabileceğini criticalbölümler.
Dan R

@DanRoche: Evet, çok haklısın. Bu ifadenin hiçbir zaman doğru olduğunu düşünmüyorum, şimdi düzelteceğim.
Jonathan Dursi

Birkaç gün önce bir OpenMP eğitimini takip ettim ve anladığım kadarıyla iki farklı kodda bir fark var. Yani sonuç farklı olabilir çünkü kritik bölüm komutun bir süre boyunca bir evre tarafından yürütülmesini sağlar, ancak komutun şu olması mümkündür: g_qCount = g_qCount + 1; 1. evre için g_qCount sonucunu sadece yazma tamponunda depolar ve 2. evre g_qCount değerini aldığında, yazma tamponundaki değil, sadece RAM'deki olanı okur. Atomik talimat, talimatın verileri belleğe
akıtmasını sağlar

31

OpenMP'de, tüm adlandırılmamış kritik bölümler birbirini dışlar.

Kritik ve atomik arasındaki en önemli fark, atomik'in yalnızca tek bir görevi koruyabilmesi ve bunu belirli operatörlerle kullanabilmenizdir.


13
Bu, önceki cevabın bir yorumu (veya düzeltmesi) olsa iyi olur.
kynan

20

Kritik Bölüm:

  • Kod bloklarının serileştirilmesini sağlar.
  • Doğru "ad" etiketi kullanımıyla blok gruplarını serileştirmek için genişletilebilir.

  • Yavaş!

Atomik işlem:

  • Çok daha hızlı!

  • Yalnızca belirli bir işlemin serileştirilmesini sağlar.


9
Ancak bu cevap çok okunabilir ve ilk cevabın harika bir özeti olacaktır
Michał Miszczyszyn

7

En hızlı yol ne kritik ne de atomiktir. Yaklaşık olarak, kritik bölümlü ekleme, basit eklemeye göre 200 kat, atomik ekleme, basit eklemeye göre 25 kat daha pahalıdır.

En hızlı seçenek (her zaman geçerli değildir), her bir iş parçacığına kendi sayacını vermek ve toplam toplama ihtiyacınız olduğunda azaltma işlemi yapmaktır.


2
Açıklamanızda bahsettiğiniz tüm sayılara katılmıyorum. X86_64 varsayıldığında, atomik işlemin kabaca bir döngü maliyetinde birkaç döngü ek yükü (bir önbellek hattını senkronize etme) olacaktır. Aksi takdirde '' gerçek paylaşım '' maliyetiniz olsaydı, genel gider nihildir. Kritik bir bölüm bir kilit maliyetine neden olur. Kilidin önceden alınmış olup olmadığına bağlı olarak, ek yük kabaca 2 atomik talimat VEYA programlayıcının iki çalışması ve uyku süresidir - bu genellikle 200x'ten önemli ölçüde daha fazla olacaktır.
Klaas van Gend

6

Sınırlamaları atomicönemlidir. OpenMP özelliklerinde ayrıntılı olarak belirtilmelidirler . MSDN hızlı bir kopya sayfası sunuyor, çünkü bu değişmezse şaşırmam. (Visual Studio 2012, Mart 2002'den itibaren bir OpenMP uygulamasına sahiptir.) MSDN'den alıntı yapmak için:

İfade ifadesi aşağıdaki biçimlerden birine sahip olmalıdır:

xbinop =expr

x++

++x

x--

--x

Önceki ifadelerde: skaler tipte xbir lvalueifadedir. exprskaler tipte bir ifadedir ve tarafından belirtilen nesneye başvurmaz x. binop aşırı yüklenmiş bir operatör değildir ve biri +, *, -, /, &, ^, |, <<, ya da >>.

Aksi takdirde kritik bölümleri atomickullanabileceğiniz ve adlandırabileceğiniz durumlarda kullanmanızı öneririm . Bunları adlandırmak önemlidir; Bu şekilde baş ağrılarında hata ayıklamaktan kaçınacaksınız.


1
Hepsi bu kadar değil, diğer gelişmiş atom direktiflerimiz var: #pragma omp aromik güncelleme (veya okuma, yükseltme, yazma, yakalama), böylece başka yararlı bir açıklama yapmamıza olanak tanıyor
pooria

1

Zaten burada harika açıklamalar. Ancak biraz daha derine dalabiliriz. OpenMP'deki atomik ve kritik bölüm kavramları arasındaki temel farkı anlamak için önce kilit kavramını anlamalıyız . Neden kilit kullanmamız gerektiğini gözden geçirelim .

Paralel bir program, birden çok iş parçacığı tarafından yürütülüyor. Deterministik sonuçlar ancak ve ancak bu iş parçacıkları arasında senkronizasyon gerçekleştirirsek gerçekleşir . Elbette, iş parçacıkları arasında senkronizasyon her zaman gerekli değildir. Senkronizasyonun gerekli olduğu durumlara atıfta bulunuyoruz .

Çok evreli bir programda iş parçacıklarını senkronize etmek için kilit kullanacağız . Erişimin bir seferde yalnızca bir iş parçacığı ile sınırlandırılması gerektiğinde, kilit devreye girer. Kilit kavramı uygulama işlemcisinden işlemciye değişebilir. Algoritmik bir bakış açısından basit bir kilidin nasıl çalıştığını öğrenelim.

1. Define a variable called lock.
2. For each thread:
   2.1. Read the lock.
   2.2. If lock == 0, lock = 1 and goto 3    // Try to grab the lock
       Else goto 2.1    // Wait until the lock is released
3. Do something...
4. lock = 0    // Release the lock

Verilen algoritma, aşağıdaki gibi donanım dilinde uygulanabilir. Tek bir işlemci varsayacağız ve buradaki kilitlerin davranışını analiz edeceğiz. Bu uygulama için aşağıdaki işlemcilerden birini varsayalım: MIPS , Alpha , ARM veya Power .

try:    LW R1, lock
        BNEZ R1, try
        ADDI R1, R1, #1
        SW R1, lock

Bu program iyi görünüyor, ama değil. Yukarıdaki kod önceki sorundan muzdariptir; senkronizasyon . Sorunu bulalım. Kilidin başlangıç ​​değerinin sıfır olduğunu varsayın. Eğer iki iş parçacığı bu kodu çalıştırırsa, biri SW R1'e ulaşabilir , diğeri kilit değişkenini okumadan önce kilitlenebilir . Böylece ikisi de kilidin serbest olduğunu düşünüyor . Bu sorunu çözmek için, basit LW ve SW yerine sağlanan başka bir talimat vardır . Oku-Değiştir-Yaz talimatı olarak adlandırılır . Bir seferde kilit edinme prosedürü sadece yapılır tek ipliğini garanti eden karmaşık bir talimattır (alt talimatlardan oluşur) . Farkı Oku-Değiştirme-yazmaBasit Okuma ve Yazma talimatlarıyla karşılaştırıldığında , Yükleme ve Saklama için farklı bir yol kullanmasıdır . Kullandığı LL kilit değişken ve yük (Bağlantılı Load) SC kilit değişkenine yazma için (Mağaza Koşullu). Kilit edinme prosedürünün tek bir iş parçacığı tarafından yapılmasını sağlamak için ek bir Bağlantı Kaydı kullanılır. Algoritma aşağıda verilmiştir.

1. Define a variable called lock.
2. For each thread:
   2.1. Read the lock and put the address of lock variable inside the Link Register.
   2.2. If (lock == 0) and (&lock == Link Register), lock = 1 and reset the Link Register then goto 3    // Try to grab the lock
       Else goto 2.1    // Wait until the lock is released
3. Do something...
4. lock = 0    // Release the lock

Bağlantı kaydı sıfırlandığında, başka bir iş parçacığı kilidin serbest olduğunu varsayarsa, artan değeri kilide tekrar yazamaz. Böylece, kilide erişimin eşzamanlılığı değişkenine elde edilir.

Kritik ve atomik arasındaki temel fark şu fikrinden gelir:

Asıl değişkeni (üzerinde bir işlem yapıyoruz) kilit değişkeni olarak kullanırken neden kilitleri (yeni bir değişken) kullanalım?

Kilitler için yeni bir değişken kullanmak kritik bölüme yol açarken, gerçek değişkeni kilit olarak kullanmak atomik konsepte yol açacaktır . Kritik bölüm, gerçek değişken üzerinde çok sayıda hesaplama yaptığımızda (birden fazla satır) kullanışlıdır. Bunun nedeni, bu hesaplamaların sonucu gerçek değişken üzerine yazılamazsa, sonuçları hesaplamak için tüm prosedürün tekrarlanması gerekir. Bu, yüksek hesaplamalı bir bölgeye girmeden önce kilidin serbest bırakılmasını beklemeye kıyasla zayıf bir performansa yol açabilir. Bu nedenle, tek bir hesaplama (x ++, x--, ++ x, --x, vb.) Yapmak istediğinizde atom direktifini kullanmanız veyoğun bölüm tarafından hesaplama açısından daha karmaşık bir bölge yapıldığında kritik yönerge.


-5

Yalnızca tek bir talimat için karşılıklı dışlamayı etkinleştirmeniz gerektiğinde atomik göreceli olarak performans açısından verimlidir, benzer omp kritik için doğru değildir.


13
Bu, kabul edilen cevabın açıklama olmaksızın kötü bir şekilde yeniden ifade edilmesinden başka bir şey değildir.
Yüksek Performans Mark

-5

atomic tek bir ifadedir Kritik bölüm, yani bir ifade yürütme için kilitliyorsunuz

kritik bölüm bir kod bloğu üzerindeki kilittir

İyi bir derleyici, ikinci kodunuzu ilkiyle aynı şekilde çevirecektir.


Bu açıkça yanlış. Lütfen anlamadığınız şeyler hakkında konuşma.
jcsahnwaldt Reinstate Monica
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.