Sabit doğruluk performansı artırabilir mi?


92

C veya C ++ kodunuzda const-doğruluğunu zorlamanın sadece sürdürülebilirlik açısından iyi bir uygulama olmadığını, aynı zamanda derleyicinizin optimizasyonlar gerçekleştirmesine de izin verebileceğini defalarca okudum. Bununla birlikte, tam tersini de okudum - performansı hiç etkilemiyor.

Bu nedenle, const doğruluğunun derleyicinize programınızın performansını iyileştirmede yardımcı olabileceği örnekleriniz var mı?


50
Süreklilik, sürdürülebilirlik açısından EN İYİ uygulamalardan biridir. C ++ kodunuz sabit doğru değilse, temelde felaketin gelmesini bekleyen bir saçmalık yığınıdır. Performansı etkilemesi amaçlanmamıştır.

2
@Neil Butterworth: Ne yazık ki tersi doğru değil.
Beta

6
constPerformans farkı yaratan bir örnek : stackoverflow.com/questions/1121791/… . Aslında bu bir uygulama kalitesi sorunuydu. constderleyicinin optimizasyonu yasal olarak yapıp yapamayacağını belirlemedi , ancak derleyicinin sürümü eksik olduğunda bunu yapamadı.
Steve Jessop

3
Eminim "morgennebel" ilk cümlede bir "sadece" eksiktir: "sadece iyi bir uygulama değildir" ile çok daha mantıklı.
IanH

2
@IanH Evet, bunu düşündüm. Ancak OP'nin açıklığa kavuşturmak için bolca zamanı oldu. Soru gönderen ve sonra ortadan kaybolan insanlar beni gerçekten sinirlendiriyor.

Yanıtlar:


77

constdoğruluk, çünkü const_castve mutabledilde olduğu için performansı iyileştiremez ve kodun kuralları uygun şekilde ihlal etmesine izin verir. Bu durum C ++ 11'de daha da kötüleşir, burada constverileriniz örneğin bir işaretçi olabilir std::atomic, yani derleyicinin diğer evreler tarafından yapılan değişikliklere uyması gerekir.

Bununla birlikte, derleyicinin ürettiği koda bakması ve gerçekten belirli bir değişkene yazıp yazmadığını belirlemesi ve buna göre optimizasyonları uygulaması önemsizdir.

Bununla birlikte, constdoğruluk, sürdürülebilirlik açısından iyi bir şeydir. Aksi takdirde, sınıfınızın müşterileri o sınıfın dahili üyelerini bozabilir. Örneğin, standardı düşünün std::string::c_str()- eğer bir const değeri döndüremiyorsa, dizginin dahili tamponuyla uğraşabilirsiniz!

constPerformans nedenleriyle kullanmayın . Bakım nedenleriyle kullanın.


31
"dizenin dahili tamponuyla uğraşabilirsiniz!" - en önemlisi, yanlışlıkla dahili tamponla uğraşabilirsiniz. Derleyici hataları const, "aptalca bir şey yapıyorsun" diyen tabelalardır.
Steve Jessop

4
... ve sabit yayınlar, "bu kodun yazarı zekice bir şeyler yapmaya çalışıyor" diyen tabelalardır ;-)
Steve Jessop

5
@Steve Jessop - veya const-cast, "Sabit doğru bir kod grubunu sabit olmayan bir kodla birleştirmeye çalışıyorum ve ikisini de düzeltemiyorum" diyen tabelalardır. Hangi, size söyleyeyim, hiçbir şekilde zekice, sadece sinir bozucu.
Michael Kohne

7
@Michael - evet, doğru nokta. Belki de orijinal tabela "aptalca bir şey yapıyorsun" değil, "birisi aptalca bir şey yapıyor".
Steve Jessop

Godbolt ve Arduino bana sabit doğruluğun sadece eğlence için olmadığını söyledi.
dgrat

31

Evet yapabilir.

Çoğu const, tamamen programcının yararınadır ve derleyicinin optimizasyonuna yardımcı olmaz, çünkü onları uzaklaştırmak yasaldır ve bu nedenle derleyiciye optimizasyon için yararlı hiçbir şey söylemezler. Bununla birlikte, bazı constURL'ler (yasal olarak) atılamaz ve bunlar derleyiciye optimizasyon için yararlı bilgiler sağlar.

Örnek olarak, bir consttürle tanımlanan genel bir değişkene erişim satır içi olabilirken, türsüz biri satır içi constolamaz çünkü çalışma zamanında değişebilir.

https://godbolt.org/g/UEX4NB

C ++:

int foo1 = 1;
const int foo2 = 2;

int get_foo1() {
    return foo1;
}

int get_foo2() {
    return foo2;
}

asm:

foo1:
        .long   1
foo2:
        .long   2
get_foo1():
        push    rbp
        mov     rbp, rsp
        mov     eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address
        pop     rbp
        ret
get_foo2():
        push    rbp
        mov     rbp, rsp
        mov     eax, 2 ; foo2 has been replaced with an immediate 2
        pop     rbp
        ret

Pratik anlamda, constperformansı artırabilirken, çoğu durumda olmayacağını veya artacağını, ancak değişikliğin fark edilmeyeceğini unutmayın. Birincil faydası constoptimizasyon değildir.


Steve Jessop, bahsetmeye değer bir şeyi ortaya çıkaran orijinal soruya ilişkin yorumunda başka bir örnek veriyor. Bir blok kapsamında, derleyici değişkenin consttüm kullanımlarını görebildiğinden, bir derleyicinin bir değişkenin değişip değişmeyeceğini belirlemesi ve buna göre optimize etmesi mümkündür. Bunun aksine, yukarıdaki örnekte, foo1diğer çeviri birimlerinde değiştirilebileceğinden, değiştirilip değiştirilmeyeceğini tahmin etmek imkansızdır . Sanırım varsayımsal duyarlı bir ultra derleyici tüm bir programı analiz edebilir ve satır içi erişimin geçerli olup olmadığını belirleyebilir foo1... ancak gerçek derleyiciler bunu yapamaz.


@ericcurtin Bu yüzden cevapta derleyiciden bahsetmedim. Normalde, oluşturulan derlemeyi gönderirken, derleyiciyi ve sürümü belirttiğimden emin olurdum, ancak bu, her büyük iyileştirici derleyicinin gerçekleştireceği bir optimizasyondur, bu nedenle bunun bir derleyiciye özgü olduğu izlenimini vermek istemedim.
Praxeolitic

1
@Acorn İşte aynı örnek, ancak bir sınıf nesnesiyle: godbolt.org/z/R-Zfgc . Ayrıca, örnekteki değişkenlerin harici bağlantıları vardır.
Praxeolitic

6

benim deneyimime göre, hayır

Skaler değişkenler için derleyici, değerin ne zaman değiştirildiğini belirleyebilir ve gerekli optimizasyonu kendisi gerçekleştirebilir.

Dizi işaretçileri için, const doğruluğu, potansiyel örtüşme problemlerinin varlığında değerlerin gerçekten sabit olacağının garantisi değildir. Bu nedenle derleyici, optimizasyonları gerçekleştirmek için tek başına const değiştiricisini kullanamaz

optimizasyon arıyorsanız, __restrict__ya da özel işlev değiştiricileri / nitelikleri göz önünde bulundurmalısınız : http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html


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.