2010-01-11 10 views
27

Aşağıdakileri göz önünde bulundurun:C++ derleyicileri, const başvuru POD parametrelerinin kopyaya geçirerek geçişi optimize eder mi?

struct Point {double x; double y;}; 

double complexComputation(const& Point p1, const Point& p2) 
{ 
    // p1 and p2 used frequently in computations 
} 

Derleyiciler sık ​​sık atıfta bulunmayı önlemek için aktarım yoluyla aktarımı en uygun hale getiriyor mu? Başka bir deyişle complexComputation'u şu şekle dönüştürün:

double complexComputation(const& Point p1, const Point& p2) 
{ 
    double x1 = p1.x; double x2 = p2.x; 
    double y1 = p1.y; double y2 = p2.y; 
    // x1, x2, y1, y2 stored in registers and used frequently in computations 
} 

Nokta bir POD olduğu için, arayanın arkasında bir kopya oluşturarak yan etki olamaz, değil mi?

Durum buysa, POD nesnelerini her zaman const referansına göre geçirebilirim, ne kadar küçük olursa olsun ve en uygun geçen semantikler hakkında endişelenmenize gerek yok. Sağ?

DÜZENLEME: Özellikle GCC derleyicisiyle ilgileniyorum. Sanırım bir test kodu yazmalı ve ASM'ye bakmalıyım.

+0

Bu soruyu araştırmayı denedim, ancak abc'nin değer geçişi, başvuru kaynağı, vb. Hakkında isabetlerle gelmeye devam ettim. –

+3

Genellikle, bunun tersi daha iyi bir yaklaşım olabilir (http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/). Değere göre geçiş yapın ve derleyiciyi – jalf

+0

+1'e istediği zaman referans olarak iletmesine izin verin. İyi soru –

cevap

4

Her derleyici için konuşamıyorum, ancak genel yanıt değil. Bu optimizasyonu yapmayacaktır.

C++ 'da const'a yapılan dökümün, bazılarının düşündüğüne göre optimizasyonu etkilemediğini öğrenmek için bkz. GOTW#81.

7

Derleyiciniz kesinlikle lift Gerekirse, üye üye değişkenlerini registerlara kaydedin. Bununla birlikte, bu, derleyicinin işlev çağrısını kendisini değere dönüştürerek dönüştürmesiyle aynı değildir.

Hangi en iyileştirmelerin yapıldığını görmek için oluşturulan grubu incelemelisiniz.

Ve FWIW, kullandığım genel kural, tüm primative tiplerini değer ve tüm sınıflar/UDT'leri (POD'lar veya değil) yapabildiğim zaman const referansı ile iletmek ve derleyicinin yapılacak en iyi şeyi ayırmasına izin vermektir. Derleyicinin yaptığı şeyin ayrıntılarıyla kendimizi endişelendirmemeliyiz, bizden çok daha zeki.

+2

Karşılaştırma yapmamayı/profil yapmamızı istemedikçe endişelenmemeye katılıyorum. Ama bir derleyicinin gerçekten bu tür bir optimizasyon yapıp yapamayacağını merak ettim. –

5

2 sayı var.

İlk olarak, değil dönüştürmek pass-by-ref derleyici pass-by-değerine, complexComputationstatic değil özellikle (yani dış nesneler tarafından kullanılabilir).

Bunun nedeni API uyumluluğudır. CPU'ya "referans" diye bir şey yoktur. Derleyici referansları işaretçilere dönüştürür. Parametreler yığın halinde veya kayıt ile geçirilir, böylece complexComputation çağıran bir kodu büyük olasılıkla (double varsayalım bir an için 4 uzunluğunda olan) olarak anılacaktır: Sadece 8 bayt yığını üzerine itilir

str x1, [r7, #0x20] 
str y1, [r7, #0x24] 
str x2, [r7, #0x50] 
str y2, [r7, #0x54] 
push r7, #0x20  ; push address of p1 onto the stack 
push r7, #0x50  ; push address of p2 onto the stack 
call complexComputation 

. , Kopya tarafından

Geçiş, diğer taraftan, yığının üzerine bütün yapı itecek, böylece montaj kodu 16 bayt yığını üzerine itildiği bu kez o

push x1 ; push a copy of p1.x onto the stack 
push y1 ; push a copy of p1.y onto the stack 
push x2 ; push a copy of p2.x onto the stack 
push y2 ; push a copy of p2.y onto the stack 
call complexComputation 

Not benzeyecek ve içerik, sayı değil işaretçilerdir. complexComputation parametresinin geçtiği anlam değiştirirse, girdi çöp olur ve programınız çökebilir.Öte yandan


, derleyici çok sık kullanılan değişkenlerin ne tanıyabilir ve saklıdır kayıtlar bunları saklamak beri

double complexComputation(const Point& p1, const Point& p2) { 
    double x1 = p1.x; double x2 = p2.x; 
    double y1 = p1.y; double y2 = p2.y; 
    // x1, x2, y1, y2 stored in registers and used frequently in computations 
} 

kolayca yapılabilir

optimizasyonu (örn r4 ~ r13 içinde daha hızlı erişim için ARM mimarisi ve birçok sXX/dXX kaydı). Eğer bir derleyici şey yaptı olmadığını bilmek istiyorum


Sonuçta, her zaman ortaya çıkan nesneler sökmeye ve karşılaştırabilirsiniz.

İlgili konular