SORU
22 AĞUSTOS 2011, PAZARTESİ


`Std::kill_dependency` ve neden kullanmak isteyeyim?

Yeni C 11 hafıza modeli hakkında çok şey okudum ve std::kill_dependency işlevi (&Mezhebi;29.3/14-15) üzerine geldim. Hiç kullanmak istemem neden anlamakta güçlük çekiyorum.

Ama, bir işe yaramadı N2664 proposal bir örnek buldum.

std::kill_dependency olmadan kod göstererek başlar. Burada, ilk satır dizin oluşturma işlemi bir bağımlılık taşıyan ikinci bir bağımlılık taşır, ve sonra do_something_with işlevi içine bir bağımlılık taşır.

r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[r2]);

Daha fazla std::kill_dependency bağımlılığı kırmak için kullandığı örnek ikinci satırı ve dizin oluşturma arasında.

r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[std::kill_dependency(r2)]);

Söyleyebileceğim kadarıyla, bu dizin oluşturma ve do_something_with çağrı bağımlılık ikinci satır önce sipariş olmadığı anlamına gelir. N2664 göre:

Bu derleyici a[r2] değerini tahmin spekülatif iyileştirmeleri gerçekleştirerek örneğin do_something_with, çağrı yeniden düzenlemek için izin verir.

20* *için arama yapmak için 21* *değeri gereklidir. Eğer varsayımsal olarak, derleyici istediği gibi" dizisi sıfırlarla doldurulur, do_something_with(0); telefon optimize etmek ve bu çağrı diğer iki talimatlara göre yeniden düzenlemek olabilir. "bilir Herhangi bir neden olabilir:

// 1
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(0);
// 2
r1 = x.load(memory_order_consume);
do_something_with(0);
r2 = r1->index;
// 3
do_something_with(0);
r1 = x.load(memory_order_consume);
r2 = r1->index;

Benim anladığım doğru mu?

do_something_with başka bir yolla başka bir iş parçacığı ile eşitler, bu x.load çağrı sipariş ve başka bir iş parçacığı açısından ne anlama geliyor?

Bana bir bağımlılık öldürmeyi tercih nelere yol açacağını kod yazıyorum, ne zaman? benim understading doğru, hala bir şey var varsayarak bu beni rahatsız ediyor:

CEVAP
22 AĞUSTOS 2011, PAZARTESİ


Memory_order_consume amacı derleyici lockless algoritmaları kırmak olabilir bazı talihsiz iyileştirmeleri yapmaz sağlamaktır. Örneğin, bu kodu göz önünde bulundurun:

int t;
volatile int a, b;

t = *x;
a = t;
b = t;

Uygun bir derleyici bu dönüşüm riski:

a = *x;
b = *x;

Böylece, bir b eşit değil. Ayrıca böyle yapabilir:

t2 = *x;
// use t2 somewhere
// later
t = *x;
a = t2;
b = t;

load(memory_order_consume) kullanarak değer yüklenen kullandığı noktaya önce taşınamaz isteriz. Diğer bir deyişle,

t = x.load(memory_order_consume);
a = t;
b = t;
assert(a == b); // always true

Standart belgeyi tek bir yapı belirli alanlar sipariş ilginizi çekebilir bir olgu olarak görüyor. Örnek:

r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[std::kill_dependency(r2)]);

Bu, etkili bir şekilde, bunu yapmak için izin verilir derleyici bildirir:

predicted_r2 = x->index; // unordered load
r1 = x; // ordered load
r2 = r1->index;
do_something_with(a[predicted_r2]); // may be faster than waiting for r2's value to be available

Ya da şu:

predicted_r2 = x->index; // unordered load
predicted_a  = a[predicted_r2]; // get the CPU loading it early on
r1 = x; // ordered load
r2 = r1->index; // ordered load
do_something_with(predicted_a);

Eğer derleyici do_something_with r1 için yükler sonucu değiştirmeyeceğini veya r2, sonra da biliyorsa bile bunu her şekilde yukarı kaldırın.

do_something_with(a[x->index]); // completely unordered
r1 = x; // ordered
r2 = r1->index; // ordered

Bu derleyici optimizasyon biraz daha özgürlük sağlar.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jorrit Jongma

    Jorrit Jongm

    17 Ocak 2008
  • SuicideSheeep

    SuicideSheee

    8 Ocak 2012
  • Ty Moss

    Ty Moss

    20 Kasım 2007