Saya punya pertanyaan konseptual: Apa artinya kepadatan kode "tinggi"? dan mengapa ini sangat penting?
sumber
Saya punya pertanyaan konseptual: Apa artinya kepadatan kode "tinggi"? dan mengapa ini sangat penting?
Kepadatan kode merujuk secara longgar pada berapa banyak instruksi mikroprosesor yang diperlukan untuk melakukan tindakan yang diminta, dan berapa banyak ruang yang digunakan setiap instruksi. Secara umum, semakin sedikit ruang yang digunakan oleh sebuah instruksi dan semakin banyak pekerjaan per instruksi yang dapat dilakukan oleh mikroprosesor, semakin padat kodenya.
Saya perhatikan bahwa Anda telah menandai pertanyaan Anda dengan tag 'arm'; Saya dapat menggambarkan kepadatan kode menggunakan instruksi ARM.
Katakanlah Anda ingin menyalin blok data dari satu tempat di memori ke yang lain. Secara konseptual, kode tingkat tinggi Anda akan terlihat seperti ini:
void memcpy(void *dest, void *source, int count_bytes)
{
char *s, *d;
s = source; d = dest;
while(count_bytes--) { *d++ = *s++; }
}
Sekarang kompiler sederhana untuk mikroprosesor sederhana dapat mengonversinya menjadi seperti ini:
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 saya agak berkarat, tetapi Anda mendapatkan ide)
Sekarang ini akan menjadi kompiler yang sangat sederhana dan mikroprosesor yang sangat sederhana, tetapi Anda dapat melihat dari contoh bahwa kita sedang melihat 8 instruksi per iterasi dari loop (7 jika kita memindahkan '1' ke register lain dan memindahkan beban di luar loop). Sama sekali tidak padat. Kepadatan kode juga memengaruhi kinerja; jika loop Anda lebih panjang karena kode tidak padat, Anda mungkin perlu lebih banyak cache instruksi untuk menahan loop. Lebih banyak cache berarti prosesor yang lebih mahal, tetapi sekali lagi decoding instruksi yang rumit berarti lebih banyak transistor untuk menguraikan instruksi yang diminta, jadi itu adalah masalah teknik klasik.
ARM cukup bagus dalam hal ini. Setiap instruksi dapat bersyarat, sebagian besar instruksi dapat menambah atau mengurangi nilai register, dan sebagian besar instruksi secara opsional dapat memperbarui flag prosesor. Pada ARM dan dengan kompiler yang cukup bermanfaat, loop yang sama mungkin terlihat seperti ini:
movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1++]
strb [r2++], r3
subs r0, r0, 1
bne loop
Seperti yang Anda lihat, loop utama sekarang 4 instruksi. Kode lebih padat karena setiap instruksi dalam loop utama melakukan lebih banyak. Ini umumnya berarti bahwa Anda dapat melakukan lebih banyak dengan jumlah memori yang diberikan, karena lebih sedikit dari itu digunakan untuk menggambarkan bagaimana melakukan pekerjaan.
Sekarang kode ARM asli sering memiliki keluhan bahwa itu bukan super padat; ini disebabkan oleh dua alasan utama: pertama, 32 bit adalah instruksi yang sangat "panjang", jadi banyak bit tampaknya terbuang untuk instruksi yang lebih sederhana, dan kedua, kode menjadi kembung karena sifat ARM: setiap instruksi adalah 32 bit panjang, tanpa kecuali. Ini berarti bahwa ada sejumlah besar nilai literal 32-bit yang tidak bisa Anda muatkan ke register. Jika saya ingin memuat "0x12345678" ke r0, bagaimana cara saya membuat kode instruksi yang tidak hanya memiliki 0x12345678 di dalamnya, tetapi juga menjelaskan "memuat literal ke r0"? Tidak ada bit yang tersisa untuk mengkode operasi yang sebenarnya. Instruksi beban literal ARM adalah binatang kecil yang menarik, dan perakit ARM juga harus sedikit lebih pintar dari perakit normal, karena harus "menangkap"
Bagaimanapun, untuk menjawab keluhan ini, ARM datang dengan mode Jempol. Alih-alih 32 bit per instruksi, panjang instruksi sekarang 16 bit untuk hampir semua instruksi, dan 32 bit untuk cabang. Ada beberapa pengorbanan dengan mode Thumb, tetapi pada umumnya pengorbanan ini mudah dilakukan karena Thumb membuatkan Anda sesuatu seperti peningkatan 40% dalam kepadatan kode hanya dengan mengurangi panjang instruksi.
"Kepadatan kode" dari set instruksi adalah ukuran berapa banyak barang yang dapat Anda masukkan ke dalam jumlah tertentu dari memori program, atau berapa banyak byte dari memori program yang Anda perlukan untuk menyimpan sejumlah fungsionalitas tertentu.
Seperti yang ditunjukkan Andrew Kohlsmith, bahkan pada MCU yang sama, kompiler yang berbeda dapat memperoleh kerapatan kode yang berbeda.
Anda mungkin menikmati membaca "Serangga dunia komputer" oleh Miro Samek, yang membandingkan berbagai MCU.
sumber