2010-09-22 14 views
6

Bir kurs için bir derleyici yazıyorum. En iyi şekilde nasıl başa çıkılacağından emin olamadığım bazı optimizasyon sorunları yaşadım. Giriş dilinden, yazmaçlarda tutulması gereken N yerel değişkenleri kullanan (veya hızlı hesaplamalar için) bir süre döngü olduğunu varsayalım. N> K, kayıtların sayısını varsayalım. Koşul döngüsünün, while döngüsünün sonuna doğru değiştirilme şansı vardır.Derleyici kod oluşturma - koşullu bloklar içinde kayıt ayırma

Örneğin, x için kayıt varsayalım önce aşağıdaki ifadeyi belirlendi (en i386 üzerinde% eax diyelim): x dökülecek için daha fazla ifadeleri kodunda

while (x) { x = x - 1 ; /* more statements */ } 

, bu mümkün Yığına geri dön. Kod, x yeniden değerlendirmek için while döngüsünün başına atlarsa,% eax kullanmaya çalışır - ancak bu şimdi x değerinin bile tutulmayabilir. Bu yüzden ben ise deyimi (böylece kayıtları kod üretecinin perspektifinden boş olarak görülüyor) önce tüm modifiye kayıtlarını dökmek için kod zorlamak kullanıyorum

 movl -8(%ebp), %eax  # eax <- x 
     ....      # do stuff but let x stay in %eax 
_LOOP1: cmpl $0, %eax 
     .... 
     movl -12(%ebp), %eax  #eax now holds something else 
     .... 
     jmp _LOOP1 

Bir çözüm gibi bir şey olabilir. While döngüsünün etiketinden sonra, kod her şeyi gerektiğinde bir kayıt defterine yüklemelidir. Benim çözüm biraz konu dışı veya gereksiz olduğu gibi

 movl -8(%ebp), %eax  # eax <- x 
     ....      # do stuff but let x stay in %eax 
     movl %eax, -8(%ebp)  # spilling and clearing all registers 
_LOOP1: movl -8(%ebp), %eax  # get a register for x again 
     cmpl $0, %eax 
     .... 
     movl -12(%ebp), %eax  # eax now holds something else 
     .... 
     movl %eax, -8(%ebp)  # spill to prevent overwrite 
     jmp _LOOP1 

Öyle görünüyor:

Benim çözüm böyle bir şeydir. Burada unuttuğum bazı genel optimizasyon hile var mı?

DÜZENLEME: Ayrıca, eğer varsa ve eğer varsa, koşullu durumlar için benzer bir durumun meydana geldiğini de belirtmek isterim. Bu durum onlar için gerçekleşir çünkü bir kayıt için koşulun içinde bir değişken için bir kayıt tahsis edilebilir, ancak kod üreteci daha sonra her şey için oraya taşındığını varsayar. Bu dava ile uğraşmak için neredeyse aynı yaklaşıma sahibim.

cevap

4

Burada aradığınız genel teknik genellikle "canlı aralık bölme" olarak adlandırılır. Bu terim için bir Google Search, bir dizi farklı kağıda işaretçiler verecektir. Temelde fikir, tek bir değişkeni (örneğinizdeki x), her biri ayrılma noktasında bir sonraki noktaya kopyalanan ayrık canlı aralıklarla çoklu değişkenlere bölmek istediğinizdir. Yani, döngüden önce x1'e sahip olacaksınız, bu da while'dan hemen önce x.1'e kopyalandı ve döngüde bu şekilde kullanıldı. Daha sonra döngüden hemen sonra, x.1'i x.2'ye kopyalayın ve bunu döngüden sonra kullanın. Bölünmüş varsların her biri, farklı bir kayıt (veya yığın yuvası) için potansiyel olarak tahsis edilecektir.

Burada çok fazla zorlama var - kodda çok fazla değişkene yol açan çok fazla değişken var, kayıt ayırma çok daha yavaş oluyor ve gereksiz kopyalara yol açıyor.

+0

Henüz buna bakmak için fazla zamanım olmadı, ancak ek karmaşıklık maliyetinde performansta çok az kazanç olduğu görünüyor? – Kizaru

+0

Kazanılacak olan kod, derlenen kodlara göre büyük ölçüde değişir (tüm derleyici optimizasyonlarında olduğu gibi). Çok az sayıda optimizasyon, kod hızını genel olarak birkaç yüzde daha fazla etkiler. –

+0

Teşekkürler. Ödülünü ben verdim. İlk yorumumu gönderdiğimde bunu yapmak istedim. Bazı test durumlarından sonra, optimizasyon gerçekten de minimaldir (i386 için). MIPS gibi bir mimaride faydalı olacağını umuyorum. – Kizaru

İlgili konular