`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ğindo_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
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.
Neden geliştirme amaçlı WEBrick yerine...
Neden't ben PHP mysql_* fonksiyon...
Neden nesne yerine bir işaretçi kendis...
Neden easy_install pip üzerinde kullan...
Neden't varsa PyPy 6.3 kat daha h...