Yanıtlar:
Kod yoğunluğu, istenen bir eylemi gerçekleştirmek için kaç mikroişlemci talimatı gerektiğini ve her komutun ne kadar yer kapladığını gevşekçe ifade eder. Genel olarak konuşursak, bir talimat ne kadar az yer kaplar ve bir mikroişlemcinin talimat başına ne kadar fazla iş yaparsa kodu o kadar yoğun olur.
Sorunuzu 'arm' etiketi ile etiketlediğinizi fark ettim; ARM yoğunluğunu kullanarak kod yoğunluğunu gösterebilirim.
Diyelim ki bir veri bloğunu bellekteki bir yerden başka bir yere kopyalamak istiyorsunuz. Kavramsal olarak, üst düzey kodunuz şöyle görünecektir:
void memcpy(void *dest, void *source, int count_bytes)
{
char *s, *d;
s = source; d = dest;
while(count_bytes--) { *d++ = *s++; }
}
Şimdi basit bir mikroişlemci için basit bir derleyici bunu aşağıdaki gibi bir şeye dönüştürebilir:
movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1]
strb [r2], r3
movl r3, 1
add r1, r3
add r2, r3
sub r0, r3
cmp r0, 0
bne loop
(ARM'm biraz paslı, ama fikri anladın)
Şimdi bu çok basit bir derleyici ve çok basit bir mikroişlemci olurdu, ancak örnekten, döngünün yinelemesi başına 8 talimata baktığımızı görebilirsiniz ('1'i başka bir kayda taşır ve yükü taşırsak 7 döngü dışında). Bu hiç de yoğun değil. Kod yoğunluğu performansı da etkiler; kod yoğun olmadığı için döngüleriniz daha uzunsa, döngüyü tutmak için daha fazla önbellek gerekebilir. Daha fazla önbellek daha pahalı bir işlemci anlamına gelir, ancak daha sonra karmaşık komut kod çözme, istenen talimatın şifresini çözmek için daha fazla transistör anlamına gelir, bu yüzden klasik bir mühendislik problemidir.
ARM bu açıdan oldukça iyi. Her talimat koşullu olabilir, çoğu talimat kayıtların değerini artırabilir veya azaltabilir ve çoğu talimat isteğe bağlı olarak işlemci bayraklarını güncelleyebilir. ARM'de ve orta derecede kullanışlı bir derleyiciyle, aynı döngü şöyle görünebilir:
movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1++]
strb [r2++], r3
subs r0, r0, 1
bne loop
Gördüğünüz gibi, ana döngü şimdi 4 talimattır. Ana döngüdeki her komut daha fazlasını yaptığı için kod daha yoğundur. Bu genellikle belirli bir bellekle daha fazlasını yapabileceğiniz anlamına gelir, çünkü işin nasıl yapılacağını tanımlamak için daha az kullanılır.
Şimdi yerli ARM kodu genellikle çok yoğun olmadığı şikayetine sahipti; Bu iki ana nedenden kaynaklanmaktadır: birincisi, 32 bit çok "uzun" bir talimattır, bu yüzden daha basit talimatlar için çok sayıda bit boşa harcanmış gibi görünür ve ikincisi, ARM'nin doğası nedeniyle kod şişirilir: her talimat 32'dir istisnasız uzun bit. Bu, bir kayıt defterine yükleyemeyeceğiniz çok sayıda 32 bit değişmez değer olduğu anlamına gelir. Eğer "0x12345678" r0 içine yüklemek istersem, sadece içinde 0x12345678 değil, aynı zamanda "r0 için literal yükü" olan bir komutu nasıl kodlayabilirim? Gerçek işlemi kodlamak için kalan bit yok. ARM yük hazır talimatı ilginç bir küçük canavar ve ARM montajcısı da normal montajcılardan biraz daha akıllı olmalı, çünkü "yakalamak"
Her neyse, bu şikayetleri cevaplamak için ARM Thumb modu ile geldi. Talimat başına 32 bit yerine, talimat uzunluğu hemen hemen tüm talimatlar için 16 bit ve dallar için 32 bittir. Başparmak modu ile birkaç fedakarlık vardı, ancak genel olarak bu fedakarlıkları yapmak kolaydı çünkü Thumb sadece talimat uzunluğunu azaltarak kod yoğunluğunda% 40'lık bir iyileşme gibi bir şey elde etti.
Bir komut kümesinin "kod yoğunluğu", belirli bir program belleğine ne kadar şey alabileceğinizin veya belirli bir işlevsellik miktarını depolamak için kaç baytlık program belleğinin gerekli olduğunun bir ölçüsüdür.
Andrew Kohlsmith'in belirttiği gibi, aynı MCU'da bile, farklı derleyiciler farklı kod yoğunluğu elde edebilir.
Çeşitli MCU'ları karşılaştıran Miro Samek'in "Bilgisayar dünyasının böcekleri" ni okumaktan keyif alabilirsiniz .