Tentang Kepadatan Kode dan definisinya

9

Saya punya pertanyaan konseptual: Apa artinya kepadatan kode "tinggi"? dan mengapa ini sangat penting?

Quaremz
sumber

Jawaban:

24

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.

akohlsmith
sumber
Jawaban yang sangat bagus. Sangat luar biasa.
pingswept
Jangan lupa menyebutkan Thumb2, yang merupakan peningkatan lebih besar untuk sebagian besar aplikasi.
Yann Ramin
Sangat menarik dibaca. Saya belajar banyak hanya membaca pertanyaan dan jawaban di situs ini.
onaclov2000
Terima kasih banyak Andrew, jawaban yang sangat baik, itu banyak membantu saya dengan keraguan saya :)
Quaremz
Ini juga bisa dilakukan dengan menyebutkan secara singkat bagaimana kepadatan kode dipengaruhi oleh RISC vs CISC (dengan RISC umumnya lebih rendah dari CISC karena arsitektur CISC cenderung memiliki lebih banyak instruksi yang dapat melakukan lebih banyak tetapi dapat menghasilkan jaringan pipa yang lebih panjang / lebih rumit sementara RISC difokuskan pada instruksi yang lebih sederhana yang memungkinkan jaringan pipa yang lebih sederhana, sehingga kepadatan kode RISC lebih rendah).
JAB
1

"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.

davidcary
sumber