6 Soru: C ++ 11 standart bir bellek modeli tanıttı. Bunun anlamı ne? Ve C ++ programlamayı nasıl etkileyecek?

tarafından oluşturulan soru Fri, Nov 23, 2018 12:00 AM

C ++ 11 standart bir bellek modeli getirdi, fakat bu tam olarak ne anlama geliyor? Ve C ++ programlamayı nasıl etkileyecek?

Bu makale ( Gavin tarafından Herb Sutter 'dan alıntı yapan Clarke /p>

  

Bellek modeli, C ++ kodu anlamına gelir.   şimdi aramak için standart bir kütüphane var   derleyiciyi kim yapmış olursa olsun   ve hangi platformda çalıştığını.   Kontrol etmenin standart bir yolu var.   farklı konu   İşlemcinin hafızası.

     

"Bölmekten söz ederken   [code] farklı çekirdeklerde   standartta hakkında konuşuyoruz   Hafıza modeli. Gidiyoruz   kırmadan optimize etmek   varsayımların ardından insanlar gidiyor   Kodu girmek için, " Sutter " dedi.

İnternette mevcut olan bu ve benzer paragrafları ezberleyebilirim (doğumdan beri kendi bellek modelime sahip olduğum gibi: P) ve hatta başkaları tarafından sorulan sorulara cevap olarak gönderebilir, ancak dürüst olmak gerekirse, bunu tam olarak anlamıyorum.

C ++ programcıları daha önce çok parçacıklı uygulamalar geliştirmek için kullanıldı, peki POSIX veya Windows veya C ++ 11 konuları nasıl olur? Faydaları nelerdir? Alt düzey detayları anlamak istiyorum.

Ayrıca, C ++ 11 bellek modelinin bir şekilde C ++ 11 çoklu iş parçacığı desteği ile ilgili olduğunu da hissediyorum. Öyleyse, tam olarak nasıl? Neden ilişkili olmalılar?

Çoklu iş parçacığı içindekilerin nasıl çalıştığını ve genel olarak bellek modelinin ne anlama geldiğini bilmediğim için, lütfen bu kavramları anlamama yardımcı olun. : -)

    
1743
6 Yanıtlar                              6                         

İlk önce, bir Dil Avukatı gibi düşünmeyi öğrenmelisiniz.

C ++ özelliği herhangi bir derleyiciye, işletim sistemine veya CPU'ya referans vermez. Gerçek sistemlerin genelleştirilmesi olan bir soyut makineye atıfta bulunur. Dil Avukatı dünyasında, programcının işi soyut makineye kod yazmaktır; derleyicinin görevi bu kodu bir beton makinesinde gerçekleştirmektir. Spesifikasyona katı bir şekilde kod yazarak, bugün veya 50 yıl sonra, uyumlu bir C ++ derleyicisine sahip herhangi bir sistemde kodunuzun derlenip çalıştırılmayacağından emin olabilirsiniz.

C ++ 98 /C ++ 03 şartnamesindeki soyut makine, temel olarak tek iş parçacıklıdır. Bu nedenle, şartnameye göre "tamamen taşınabilir" olan çok dişli C ++ kodunu yazmak mümkün değildir. Teknik özellik, bellek yüklerinin ve depoların atomikliği veya yüklerin ve depoların olabileceği siparişi hakkında hiçbir şey söylemiyor, muteksiler gibi şeyleri boşver.

Elbette, pthreads veya Windows gibi belirli somut sistemler için pratikte çok dişli kod yazabilirsiniz. Ancak C ++ 98 /C ++ 03 için çok iş parçacıklı kod yazmanın standart yolu yoktur.

C ++ 11'deki soyut makine, tasarım tarafından çok iş parçacıklı. Ayrıca iyi tanımlanmış bir bellek modeline sahiptir; yani, derleyicinin belleğe erişme konusunda yapabileceklerini ve yapamayabileceklerini söylüyor.

Bir çift genel değişkene aynı anda iki iş parçacığıyla erişilen aşağıdaki örneği göz önünde bulundurun:

 
           Global
           int x, y;

Thread 1            Thread 2
x = 17;             cout << y << " ";
y = 37;             cout << x << endl;

İplik 2 çıktısı ne olabilir?

C ++ 98 /C ++ 03 altında, bu tanımsız Davranış bile değildir; Sorunun kendisi anlamsızdır çünkü standart bir "thread" olarak adlandırılan hiçbir şeyi düşünmez.

C ++ 11 altında, sonuç Tanımsız Davranış, çünkü yükler ve depoların genel olarak atomik olması gerekmez. Bu da pek bir gelişme göstermeyebilir ... Ve kendi başına, öyle değil.

Ancak C ++ 11 ile şunu yazabilirsiniz:

 
           Global
           atomic<int> x, y;

Thread 1                 Thread 2
x.store(17);             cout << y.load() << " ";
y.store(37);             cout << x.load() << endl;

Artık işler daha da ilginçleşiyor. Her şeyden önce, buradaki davranış tanımlıdır . İş parçacığı 2 şimdi 0 0 (iş parçacığı 1'den önce çalışıyorsa), 37 17 (iş parçacığı 1 sonra çalıştırıyorsa) veya 0 17 (iş parçacığı 1 x'e atanır ancak y için atanmadan önce çalışıyorsa) yazdırabilir.

Yazdırılamadığı şey 37 0, çünkü C ++ 11'deki atom yükleri /depoları için varsayılan mod, sıralı tutarlılığı zorlamaktır. Bu sadece tüm yüklerin ve mağazaların t'de olduğu gibi "sanki" olması gerektiği anlamına gelirBunları her bir dizinin içine yazdığını söylerken, sistemin sevdiği halde diziler arasındaki işlemler birleştirilebilir. Bu nedenle, atomiklerin varsayılan davranışı, yükler ve depolar için hem atomiklik hem de sıralama 'ı sağlar.

Artık modern bir CPU'da sıralı tutarlılığı sağlamak pahalı olabilir. Özellikle, derleyicinin burada her erişim arasında tam gelişmiş bellek engelleri yayması muhtemeldir. Fakat eğer algoritmanız sıra dışı yükleri ve depoları tolere edebilirse; yani, atomiklik gerektiriyorsa ancak sipariş vermiyorsa; yani, bu programdan elde edilen çıktı olarak 37 0’a tahammül edebiliyorsa, şunu yazabilirsiniz:

 
           Global
           atomic<int> x, y;

Thread 1                            Thread 2
x.store(17,memory_order_relaxed);   cout << y.load(memory_order_relaxed) << " ";
y.store(37,memory_order_relaxed);   cout << x.load(memory_order_relaxed) << endl;

İşlemci ne kadar modernse, bunun bir önceki örnekten daha hızlı olması muhtemeldir.

Son olarak, belirli yükleri ve depoları sırayla tutmanız gerekirse, şunu yazabilirsiniz:

 
           Global
           atomic<int> x, y;

Thread 1                            Thread 2
x.store(17,memory_order_release);   cout << y.load(memory_order_acquire) << " ";
y.store(37,memory_order_release);   cout << x.load(memory_order_acquire) << endl;

Bu, bizi sipariş edilen yüklere ve depolara geri götürür - yani 37 0 artık olası bir çıktı değildir - ancak minimum ek yük sağlar. (Bu önemsiz örnekte, sonuç tam gelişmiş sıralı tutarlılık ile aynıdır; daha büyük bir programda olmazdı.)

Elbette, görmek istediğiniz çıktıların 0 0 veya 37 17 olması durumunda, orijinal kodun etrafına bir muteks sarabilirsiniz. Ancak bu ana kadar okuduysanız, bunun nasıl çalıştığını zaten biliyorsunuzdur ve bu cevap zaten benim istediğimden daha uzun.

Öyleyse, en alt satırda. Muteksler mükemmeldir ve C ++ 11 onları standart hale getirir. Ancak bazen performans nedenlerinden dolayı daha düşük seviyeli ilkeller istersiniz (örneğin, klasik çift denetimli kilitleme düzeni ). Yeni standart, muteksler ve koşul değişkenleri gibi yüksek seviyeli araçlar sunar ve ayrıca atomik tipler ve çeşitli hafıza bariyerleri gibi düşük seviyeli araçlar sunar. Şimdi, tamamen standart tarafından belirtilen dilde karmaşık, yüksek performanslı eşzamanlı rutinler yazabilirsiniz ve kodunuzun hem bugünün sistemlerinde hem de yarınınkilerinde değişmeden çalışacağından emin olabilirsiniz.

Her ne kadar dürüst olsanız da, bir uzman olmadığınız ve ciddi bir düşük seviye kod üzerinde çalışmadığınız sürece, muhtemelen muteks ve koşul değişkenlerine bağlı kalmalısınız. Yapmayı düşündüğüm şey bu.

Bu konu hakkında daha fazla bilgi için bkz. bu blog sonrası .

    
2016
2018-12-01 11: 30: 53Z
  1. Güzel cevap, ancak bu yeni ilkellerin bazı gerçek örnekleri için gerçekten yalvarıyor. Ayrıca, ilkelsiz bellek siparişinin C ++ 0x öncesi ile aynı olduğunu düşünüyorum: garanti yok.
    2011-06-12 00: 37: 19Z
  2. @ John: Biliyorum, ama hala ilkelleri öğreniyorum :-). Ayrıca bayt erişimlerinin atomik olduğunu (sanırım olmasa da) garanti ettiklerini düşünüyorum, bu yüzden örneğim için "char" ile geldim ... Ama bundan% 100 emin bile değilim ... Herhangi bir iyi önermek istersen " öğretici "referansları yanıtlarıma ekleyeceğim
    2011-06-12 00: 39: 08Z
  3. @ Nawaz: Evet! Bellek erişimi derleyici veya CPU tarafından yeniden düzenlenebilir. Önbellekleri ve spekülatif yükleri (örneğin) düşünün. Sistem belleğinin etkilenme sırası, kodladığınıza benzer bir şey olamaz. Derleyici ve CPU bu yeniden sıralamaların tek iş parçacıklı kodlarını bozmadığından emin olur. Çok iş parçacıklı kod için, "bellek modeli" olası yeniden siparişleri ve iki iş parçacığı aynı yeri aynı anda okuduğunda /yazdığında ve her ikisini nasıl kontrol altına aldığınızı gösterir. Tek iş parçacıklı kod için, bellek modeli ilgisizdir.
    2011-06-12 17: 08: 46Z
  4. @ Nawaz, @Nemo - Küçük bir ayrıntı: Yeni bellek modeli, i = i++ gibi belirli ifadelerin tanımsızlığını belirlediği sürece tek iş parçacıklı kodla ilgilidir. Eski sıralama noktaları kavramı atıldı; yeni standart, daha genel bir konu dizisi olan önce konseptinin özel bir örneği olan sıralı bir ilişki kullanarak aynı şeyi belirtir.
    2011-06-13 13: 14: 58Z
  5. @ AJG85: STaslak C ++ 0x spesifikasyonunun 3.6.2 bölümünde, "Statik saklama süresi (3.7.1) veya iş parçacığı saklama süresi (3.7.2) olan değişkenler, başka bir başlatma yapılmadan önce sıfır olarak başlatılmalıdır (8.5)." X, y bu örnekte global olduğundan, statik depolama süreleri var ve bu nedenle sıfır başlatılacaklar, inanıyorum.
    2011-06-13 20: 16: 38Z

Yalnızca bellek tutarlılık modellerini (ya da kısaca bellek modellerini) anladığım analojiyi vereceğim. Leslie Lamport'un seminal makalesinden ilham alan "Zaman, Saatler ve Dağıtılmış Bir Olayların Sıralanması Sistem ". Analoji uygun ve temel bir öneme sahip, ancak birçok kişi için aşırı olabilir. Ancak, umarım bellek tutarlılığı modelleri hakkında akıl yürütmeyi kolaylaştıran zihinsel bir görüntü (resimsel bir temsildir) sağlar.

Tüm bellek konumlarının tarihçelerini, yatay eksenin adres alanını temsil ettiği (yani her bellek konumunun o eksen üzerindeki bir noktayla temsil edildiği) ve dikey eksenin zamanı temsil ettiği (zamana göre Genel olarak, zamanın evrensel bir kavramının olmadığını görüyoruz). Bu nedenle, her bir hafıza konumunda tutulan değerlerin geçmişi, bu hafıza adresindeki dikey bir sütunla temsil edilir. Her değer değişikliği, konulara yeni bir değer yazan konu başlığından kaynaklanmaktadır. Bellek resmi ile, belirli bir zamanda gözlenebilir tüm gözlemlenebilir tüm bellek konumlarının değerlerinin toplamı /birleşimi anlamına gelir belirli bir konuya göre.

"Bellek Tutarlılığı ve Önbellek Tutarlılığı Üzerine Bir Astar" 'dan alıntı yapmak

  

Sezgisel (ve en kısıtlayıcı) bellek modeli, çok parçacıklı bir uygulamanın, her bir dişlinin sıralı uygulamalarının bir araya getirilmesi gibi görünmesi gereken, sanki tek bir çekirdekte zamana göre çoğaltılmış gibi görünmesi gereken sıralı tutarlılıktır (SC). işlemci.

Genel bellek düzeni, programın bir çalışmasından diğerine değişebilir ve önceden bilinemeyebilir. SC'nin karakteristik özelliği, adres-yer-zaman diyagramındaki eşzamanlılık düzlemlerini (yani hafıza görüntüleri) temsil eden yatay dilimler kümesidir. Belirli bir düzlemde, tüm olayları (veya hafıza değerleri) aynı andadır. Tüm iş parçacıklarının hangi bellek değerlerinin eşzamanlı olduğu konusunda hemfikir olduğu bir Mutlak Zaman kavramı vardır. SC'de, her anda, tüm iş parçacıkları tarafından paylaşılan yalnızca bir bellek görüntüsü vardır. Bu, her zaman, tüm işlemciler bellek görüntüsü üzerinde anlaşır (yani, belleğin toplam içeriği). Bu, tüm iş parçacıklarının tüm bellek konumları için aynı değer sırasını görüntülediği anlamına gelmez, aynı zamanda tüm işlemcilerin tüm değişkenlerin aynı değer bileşimlerini de gözlemledikleri anlamına gelir. Bu, tüm bellek işlemlerinin (tüm bellek konumlarında) tüm iş parçacıkları tarafından aynı sırayla gözlemlendiğini söylemekle aynıdır.

Rahat bellek modellerinde, her iş parçacığı adres-boşluk-zamanını kendi yoluna göre keser, tek kısıtlama her iş parçacığının dilimlerinin birbirini geçmemesidir, çünkü tüm iş parçacıkları her bir ayrı bellek konumunun geçmişi üzerinde anlaşmalıdır. (tabii ki, farklı ipliklerin dilimleri birbirini geçebilir ve geçecektir). Dilimlemenin evrensel bir yolu yoktur (adres-mekan-zamanın ayrıcalıklı bir ayrıntısı yoktur). Dilimler düzlemsel (veya doğrusal) olmak zorunda değildir. Bunlar kavisli olabilir ve bu, bir iş parçacığının başka bir iş parçacığı tarafından yazılan sırayla yazılan değerleri okumalarını sağlayabilir. Farklı bellek konumlarının geçmişi birbirleriyle göreceli olarak rasgele kayabilir (ya da uzayabilir) Belirli bir konu tarafından görüntülendiğinde . Her iş parçacığı, hangi olayların (veya eşdeğerde, bellek değerlerinin) eşzamanlı olduğu farklı bir anlayışa sahip olacaktır. Bir iş parçacığına eşzamanlı olan olaylar kümesi (veya hafıza değerleri) diğerine eşzamanlı değildir. Bu nedenle, rahat bir bellek modelinde, tüm dişler hala her bir hafıza yeri için aynı tarihi (yani değer dizisi) izler. Ancak farklı bellek görüntülerini gözlemleyebilirler (yani tüm bellek konumlarının değerlerinin birleşimi). Aynı iş parçacığı tarafından iki farklı bellek konumu sırayla yazılsa bile, yeni yazılan iki değer diğer iş parçacıkları tarafından farklı sırayla görülebilir.

[Wikipedia'dan Resim]

Einstein’ın Özel Görelilik Teorisi hakkında bilgi sahibi olan okuyucular, neye benzediğimi anlayacaklardır. Minkowski’nin sözcüklerini bellek modellerine çevirmek: adres alanı ve zaman adres-zaman-zaman gölgesidir. Bu durumda, her gözlemci (iş parçacığı) olayların gölgelerini (yani hafıza depolar /yükler) kendi dünya çizgisine (yani zaman ekseni) ve kendi eşzamanlılık düzlemine (adres-uzay ekseni) yansıtacaktır. . C ++ 11 bellek modelindeki başlıklar, özel görelilik açısından birbirine göre hareket eden observers 'e karşılık gelir. Sıralı tutarlılık, Galilean uzay-zamanı 'na tekabül eder (yani tüm gözlemciler bir mutlak olay sırası ve küresel bir simultanelik duygusu üzerinde anlaşırlar).

Bellek modelleri ve özel görelilik arasındaki benzerlik, her ikisi de çoğunlukla nedensel bir küme olarak adlandırılan, kısmen sıralı bir olay kümesini tanımlamasından kaynaklanır. Bazı olaylar (yani hafıza depoları) diğer olayları etkileyebilir (ancak bundan etkilenmez). Bir C ++ 11 dizisi (veya fizikteki gözlemci), bir olay zincirinden (yani, tamamen düzenlenmiş bir dizi) (örn., Bellek yükler ve muhtemelen farklı adreslere depolanır) bir şey değildir.

İzafiyette, bazı sıralamalar kısmen sıralanan olayların görünüşte kaotik görüntüsüne kavuşur, çünkü tüm gözlemcilerin aynı fikirde olduğu tek geçici sıra, "zaman çizelgesi" olayları arasındaki sıralamadır (yani, herhangi biri tarafından prensipte bağlanabilir olan olaylar) partikül, vakumdaki ışık hızından daha yavaş ilerliyor). Yalnızca zaman çizelgesiyle ilgili olaylar değişmez şekilde sıralanır. Fizik Zamanı, Craig Callender .

C ++ 11 bellek modelinde, bu yerel nedensellik ilişkilerini kurmak için benzer bir mekanizma (edinim-yayım tutarlılık modeli) kullanılır.

SC'nin bırakılması için bir bellek tutarlılığı tanımı ve motivasyon sağlamak için adresinden alıntı yapacağım "Bellek Tutarlılığı ve Önbellek Tutarlılığı Üzerine Bir Astar"

  

Paylaşılan bir bellek makinesi için, bellek tutarlılığı modeli, bellek sisteminin mimari olarak görünür davranışını tanımlar. Tek bir işlemci çekirdeği için doğruluk ölçütü, “ bir doğru sonuç ” ve “ birçok yanlış alternatif ” arasındaki davranışı bölüştürür. Bunun nedeni, işlemcinin mimarisinin bir iş parçacığının yürütülmesinin belirli bir girdi durumunu sıra dışı bir çekirdekte bile iyi bir tek tanımlanmış çıktı durumuna dönüştürmesini gerektirmesidir. Ancak paylaşılan bellek tutarlılığı modelleri, birden fazla iş parçacığının yükleri ve depoları ile ilgilidir ve çoğu (daha fazla) yanlış olanı reddetmekle birlikte genellikle birçok doğru uygulamaya izin verir. Çoklu doğru uygulamaların olasılığı, ISA'nın çoklu iş parçacıklarının eşzamanlı olarak çalıştırılmasına izin vermesinden kaynaklanır, çoğu zaman farklı iş parçacıklarından gelen talimatların olası birçok olası bir araya getirilmesiyle.

     

Relaxed veya weak bellek tutarlılığı modelleri, güçlü modellerdeki çoğu bellek siparişinin gereksiz. Bir iş parçacığı on veri öğesini ve ardından bir senkronizasyon bayrağını güncellerse, programcılar genellikle veri öğelerinin birbirine göre güncellenip güncellenmediğini önemsemez, ancak yalnızca bayrak güncellenmeden önce tüm veri öğelerinin güncellenmesini önemser (genellikle FENCE talimatları kullanılarak uygulanır) ). Rahat modeller bu artan sipariş esnekliğini yakalamaya çalışır ve SC'nin hem daha yüksek performansını hem de doğruluğunu elde etmek için yalnızca programcıların “ gerektirdiği ” siparişleri korur. Örneğin, bazı mimarilerde, FIFO yazma arabellekleri, sonuçları önbelleklere yazmadan önce, her çekirdek tarafından taahhütlü (emekli) mağazaların sonuçlarını tutmak için kullanılır. Bu optimizasyon performansı arttırır ancak SC'yi ihlal eder. Yazma arabelleği, bir mağazanın servisini kaybetme gecikmesini gizler. Mağazalar yaygın olduğu için, çoğuna engel olmaktan kaçınmak önemli bir avantajdır. Tek çekirdekli bir işlemci için, bir A adresine bir yükün, yazma arabelleğinde bir veya daha fazla mağaza olmasına rağmen, en son mağazanın değerini A'ya döndürmesini sağlayarak mimari olarak görünmez hale getirilebilir. Bu genellikle, en son mağazanın değerinin A'ya A'dan yüke atlanmasıyla, "en son" program sırasına göre belirlendiğinde ya da A için bir mağazanın yazma arabelleğindeyse bir A yükünün durmasıyla yapılır. . Birden çok çekirdek kullanıldığında, her biri kendi kendine yazarak yazma arabelleğine sahip olacaktır. Yazma arabellekleri olmadan, donanım SC'dir, ancak yazma arabellekleriyle, yazma arabelleklerini çok çekirdekli bir işlemcide mimari olarak görünür kılar.

     

Bir çekirdeğin mağazadan ayrılmasını sağlayan FIFO olmayan bir yazma arabelleğine sahip olması durumunda mağaza-mağaza yeniden sıralama olabilirn girdikleri sıradan farklı bir sıra. Bu durum, ikinci vuruş vururken ilk mağaza önbelleği kaçırırsa veya ikinci mağaza daha önceki bir mağazayla birleşebilirse (örneğin, ilk mağazadan önce) oluşabilir. Yük yükleme yeniden sıralaması, program sırasındaki yönergeleri yürüten dinamik olarak zamanlanmış çekirdeklerde de olabilir. Bu, başka bir çekirdekte depoları yeniden düzenlemekle aynı şekilde davranabilir (İki iplik arasında bir araya getirme örneği bulabilir misin?). Daha eski bir yükü daha sonra bir deposuyla (bir yük deposu yeniden sıralaması) yeniden sıralamak, onu koruyan kilidi serbest bıraktıktan sonra bir değer yüklemek gibi birçok yanlış davranışa neden olabilir (mağaza kilit açma işlemi ise). Depo yükleme yeniden sıralamasının, tüm komutları program sırasına uygulayan bir çekirdeğe sahip olsa bile, yaygın olarak uygulanan FIFO yazma arabelleğindeki yerel bypass işleminden kaynaklanabileceğini unutmayın.

Önbellek tutarlılığı ve hafıza tutarlılığı bazen karışık olduğundan, bu alıntıya da sahip olmak öğreticidir:

  

Tutarlılıktan farklı olarak, önbellek tutarlılığı ne yazılım tarafından görünür ne de zorunludur. Tutarlılık, paylaşılan bellek sisteminin önbelleklerini tek çekirdekli bir sistemdeki önbellekler kadar işlevsel olarak görünmez kılmaya çalışır. Doğru tutarlılık, bir programcının yüklerin ve depoların sonuçlarını analiz ederek bir sistemin önbelleğe girip girmediğini ve nerede olacağını tespit edememesini sağlar. Bunun nedeni, doğru tutarlılığın, önbelleklerin hiçbir zaman yeni veya farklı functional davranışını etkinleştirmemesini sağlamasıdır (programcılar zamanlamayı önbellek yapısına neden olabilir. /em> bilgi). Önbellek tutarlılık protokollerinin temel amacı, tek yazarlı çoklu okuyucunun (SWMR) her bellek yeri için değişmez olmasını sağlamaktır.   Tutarlılık ve tutarlılık arasındaki önemli bir ayrım, tutarlılığın her bir yer için temel ile belirtilmiş olmasıdır; oysa tutarlılık ise tümü hafıza yerleri.

Zihinsel tablomuza devam edersek, SWMR değişmezi herhangi bir yerde en fazla bir partikül bulunması fiziksel gereksinimine karşılık gelir, ancak herhangi bir yerde sınırsız sayıda gözlemci olabilir.

    
315
2017-02-08 14: 44: 04Z
  1. + 1, özel göreliliğe sahip analoji için, aynı analojiyi kendim yapmaya çalışıyorum. Çok sık olarak, programcıları, davranışları belirli bir sırayla birbirleriyle iç içe geçmiş olan farklı iş parçacığındaki işlemler olarak davranışı yorumlamaya çalışırken, iş parçacığı kodunu araştırarak görüyorum ve bunları çok işlemcili sistemler arasında farklılıklar arasında eşzamanlılık kavramını anlatmak zorundayım. s > referans çerçeveleri < /s > konu şimdi anlamsız. Özel görelilik ile karşılaştırmak, sorunun karmaşıklığına saygı duymalarını sağlamanın iyi bir yoludur.
    2014-06-26 19: 42: 19Z
  2. Evrenin çok çekirdekli olduğu sonucuna varmalı mıyım?
    2015-04-28 11: 36: 21Z
  3. @ PeterK: Kesinlikle :) Ve işte bu zamanın fizikçi Brian Greene tarafından çok güzel bir şekilde görselleştirilmesi: youtube.com/watch?v=4BjGWLJNPcA&t=22m12s Bu," Zamanın Yanılsaması " dakika 22 ve 12 saniye.
    2015-07-19 02: 17: 28Z
  4. Sadece ben miyim yoksa 1D bellek modelinden (yatay eksen) 2B bellek modeline (eşzamanlılık düzlemlerine) geçiyor. Bunu biraz kafa karıştırıcı buluyorum ama belki de bunun nedeni yerli bir konuşmacı değilim ... Yine de çok ilginç bir okuma.
    2017-01-12 11: 31: 29Z
  5. Önemli bir bölümü unuttunuz: ", yüklerin ve mağazaların sonuçlarını analiz ederek " ... ... kesin zamanlama bilgilerini kullanmadan.
    2019-03-01 16: 22: 25Z

Bu şimdi çok yıllık bir sorudur, ancak çok pop olmakUlar, C ++ 11 bellek modeli hakkında bilgi edinmek için harika bir kaynaktan bahsetmeye değer. Bunu bir başka tam cevap haline getirmek için konuşmasını özetlemenin hiçbir anlamı görmüyorum, ancak bu verilen standardı yazan kişi olduğu için, konuşmayı izlemeye değeceğini düşünüyorum.

Herb Sutter, Channel9 sitesinde bulunan "atomik &Silahlar" adlı C ++ 11 bellek modeli hakkında üç saatlik bir konuşma yaptı. bölüm 1 ve bölüm 2 . Konuşma oldukça teknik ve aşağıdaki konuları içeriyor:

  1. Optimizasyonlar, Yarışlar ve Bellek Modeli
  2. Sipariş Verme - Ne: Alma ve Bırakma
  3. Sipariş Verme - Nasıl: Mutexes, Atomics ve /veya Çitler
  4. Derleyici ve Donanımdaki Diğer Kısıtlamalar
  5. Kod Gen & Performans: x86 /x64, IA64, GÜÇ, KOL
  6. Rahat Atomlar

Konuşma, API üzerinde ayrıntılı bir şekilde açıklanmıyor, bunun yerine, başlık altında ve sahnelerin arkasında akıl yürütme, arka plan üzerinde çalışıyor (rahat anlambilimin yalnızca standartlara eklendiğini biliyor muydunuz, çünkü POWER ve ARM senkronize yükü verimli bir şekilde desteklemiyor ?).

    
100
2017-11-05 23: 17: 25Z
  1. Bu konuşma gerçekten harikaydı, izlemeye harcayacağınız 3 saat boyunca tamamen değer.
    2015-08-31 12: 50: 22Z
  2. @ ZunTzu: çoğu video oynatıcıda hızı orijinalin 1.25, 1.5 veya hatta 2 katı olarak ayarlayabilirsiniz.
    2015-12-15 17: 48: 58Z
  3. @ eran sizde slayt var mı? Kanaldaki 9 konuşma sayfasındaki bağlantılar çalışmıyor.
    2016-08-30 02: 33: 10Z
  4. @ athos Bende yok, üzgünüm. Kanal 9 ile iletişime geçmeyi deneyin, kaldırmanın kasıtlı olduğunu sanmıyorum (tahminimce bağlantıyı Herb Sutter'dan aldıkları, olduğu gibi yayınladıkları ve daha sonra dosyaları kaldırdıkları; ama bu sadece bir spekülasyon ...). div>
    2016-08-30 06: 06: 42Z

    Bu, standardın şimdi çoklu iş parçacığını tanımladığı ve birden fazla iş parçacığı bağlamında neler olacağını tanımladığı anlamına gelir. Elbette, insanlar çeşitli uygulamalar kullanıyorlardı, ama bu neden hepimiz bir std::string sınıfını kullanabileceğimizde string'a sahip olmamız gerektiğini sormak gibi.

    POSIX konuları veya Windows konuları hakkında konuşurken, o zaman bu aynı anda çalıştırmak için bir donanım işlevi olduğundan, aslında x86 konuları hakkında konuştuğunuz gibi bir yanılsamadır. C ++ 0x bellek modeli, x86'da veya ARM'de veya MIPS ’da olsanız da garanti verir. > veya bulabileceğiniz herhangi bir şey.

        
    73
    2017-11-05 23: 06: 03Z
    1. Posix konuları x86 ile sınırlı değil. Aslında, uygulandıkları ilk sistemler muhtemelen x86 sistemleri değildi. Posix dişleri sistemden bağımsızdır ve tüm Posix platformlarında geçerlidir. Ayrıca bu bir donanım özelliği olmadığı için de doğru değil çünkü Posix iş parçacıkları aynı zamanda işbirlikçi çoklu görevler aracılığıyla da uygulanabilir. Ancak elbette çoğu iş parçacığı sorunu yalnızca donanım iş parçacığı uygulamalarında (hatta bazıları yalnızca çok işlemcili /çok çekirdekli sistemlerde) ortaya çıkar.
      2013-08-18 19: 56: 31Z

    Bir bellek modeli belirtmeyen diller için, işlemci mimarisi tarafından belirtilen bellek modeli ve dili için kod yazıyorsunuz. İşlemci, performans için bellek erişimlerini yeniden sipariş etmeyi seçebilir. Yani, eğer s veri yarışları (bir veri yarışı aynı anda birden fazla çekirdeğin /köprü iş parçacığının aynı belleğe erişmesi mümkün olduğunda) programınız işlemci bellek modeline bağımlılığı nedeniyle platformlar arası değildir. İşlemcilerin belleğin erişimini nasıl yeniden sipariş edebileceğini öğrenmek için Intel veya AMD yazılım kılavuzlarına bakabilirsiniz.

    Çok önemlisi, kilitler (ve kilitlemeli eşzamanlılık semantikleri) tipik olarak çapraz platform şeklinde uygulanırlar. Dolayısıyla, veri okları olmayan çok iş parçacıklı bir programda standart kilitler kullanıyorsanız, yapmak zorunda değilsiniz platformlar arası bellek modelleri hakkında endişelenmek .

    İlginç bir şekilde, C ++ için Microsoft derleyicileri, C ++ http://msdn.microsoft.com/en-us/library/12a04hfd (v = vs.80) .aspx . Ancak, Windows'un yalnızca x86 /x64'te çalıştığı göz önüne alındığında, bu pek bir şey ifade etmemektedir (Intel ve AMD bellek modelleri, bir dilde semantik edinme /bırakma anlamayı uygulamayı kolaylaştırır ve verimli kılar).

        
    54
    2017-11-05 23: 09: 19Z
    1. Yanıt yazıldığında, Windows'un yalnızca x86 /x64'te çalıştığı, ancak Windows'un bir anda IA64, MIPS, Alpha'da çalıştığı doğru AXP64, PowerPC ve ARM. Bugün, x86'dan oldukça farklı bir bellek olan ARM'in çeşitli sürümlerinde çalışır ve neredeyse bağışlayıcı olduğu hiçbir yerde yoktur.
      2016-12-06 10: 12: 50Z
    2. Bu bağlantı biraz bozuk ( "Visual Studio 2005 Emekli belgeler" diyor). Güncellemek ister misiniz?
      2017-11-05 23: 09: 57Z
    3. Cevap yazıldığında bile doğru değildi.
      2017-12-02 10: 14: 55Z
    4. " aynı belleğe aynı anda erişmek için " çakışan şekilde erişmek için
      2018-06-13 23: 22: 25Z

    Tüm verilerinizi korumak için muteks kullanıyorsanız, gerçekten endişelenmenize gerek yok. Mutexes her zaman yeterli sipariş ve görünürlük garantisi vermiştir.

    Şimdi, atom veya kilit içermeyen algoritmalar kullanıyorsanız, bellek modelini düşünmeniz gerekir. Bellek modeli, atomların ne zaman sipariş ve görünürlük garantisi sağladığını ve elle kodlanmış garantiler için taşınabilir çitler sağladığını tam olarak açıklar.

    Önceden, atom derleyici içselleri ya da bazı üst seviye kitaplıkları kullanarak yapılıyordu. Çitler CPU'ya özgü talimatlar (hafıza bariyerleri) kullanılarak yapılmış olabilir.

        
    25
    2011-06-11 23: 49: 53Z
    1. Daha önceki sorun, bir muteks (C ++ standardı açısından) diye bir şey olmamasıydı. Bu yüzden, size verilen tek teminat, kodu taşımadığınız sürece (garantilerdeki ufak değişikliklerin tespit edilmesi zor olduğu için) mutex üreticisi tarafından yapılmıştı. Artık, platformlar arasında taşınabilir olması gereken standart tarafından sağlanan garantileri alıyoruz.
      2011-06-12 00: 09: 32Z
    2. @ Martin: her durumda, bir şey bellek modeli, diğeri ise bu bellek modelinin üzerinde çalışan atomlar ve iş parçacığı ilkelleridir.
      2011-06-12 00: 18: 39Z
    3. Ayrıca, benim açımdan daha önce dil düzeyinde çoğunlukla bellek modeli bulunmadığı, bunun altında yatan işlemcinin bellek modeli olduğu ortaya çıkmıştı. Şimdi ana dilin bir parçası olan bir bellek modeli var; OTOH, mutekses ve benzeri her zaman bir kütüphane olarak yapılabilir.
      2011-06-12 00: 36: 01Z
    4. Bu coMutex kütüphanesini yazmaya çalışan insanlar için de gerçek bir problem olabilir. İşlemci, bellek denetleyicisi, çekirdek, derleyici ve "C kitaplığı" hepsi farklı ekipler tarafından uygulandığında ve bazıları, bu işlerin nasıl çalışması gerektiği konusunda, bazen işlerin nasıl yürüdüğü konusunda şiddetli bir anlaşmazlık içindedir. Biz sistem programcılarının güzel bir cephe sunmak için yapmaları gereken uygulamalar seviyesine hiç hoş gelmiyor.
      2011-06-12 02: 02: 15Z
    5. Dilinizde tutarlı bir bellek modeli yoksa, veri yapılarınızı basit mutekslerle korumak yeterli değildir. Tek bir iş parçacığı bağlamında mantıklı olan çeşitli derleyici optimizasyonları vardır, ancak birden çok iş parçacığı ve işlemci çekirdeği devreye girdiğinde, bellek erişimlerinin yeniden sıralanması ve diğer optimizasyonlar tanımsız davranışlar sağlayabilir. Daha fazla bilgi için bkz. Hans Boehm'in "Konular kitaplık olarak uygulanamaz": citeseer.ist.psu.edu/viewdoc/…
      2011-06-13 12: 45: 31Z
kaynak yerleştirildi İşte