Про щільність коду та його визначення


Відповіді:


24

Щільність коду слабко позначається на тому, скільки інструкцій мікропроцесора потрібно для виконання запитуваної дії та скільки місця займає кожна інструкція. Взагалі кажучи, чим менше місця займає інструкція і чим більше роботи за інструкцію може робити мікропроцесор, тим щільнішим є його код.

Я помічаю, що ви позначили своє питання тегом 'arm'; Я можу проілюструвати щільність коду за допомогою інструкцій ARM.

Скажімо, ви хочете скопіювати блок даних з одного місця в пам'яті в інше. Концептуально ваш код високого рівня виглядатиме приблизно так:

void memcpy(void *dest, void *source, int count_bytes)
{
    char *s, *d;

    s = source; d = dest;
    while(count_bytes--) { *d++ = *s++; }
}

Тепер простий компілятор для простого мікропроцесора може перетворити це на щось на зразок наступного:

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 трохи іржавий, але ви розумієте)

Тепер це був би дуже простий компілятор і дуже простий мікропроцесор, але ви можете бачити з прикладу, що ми дивимось на 8 інструкцій за ітерацію циклу (7, якщо ми перемістимо '1' в інший реєстр і перемістимо навантаження поза петлі). Це зовсім не щільно. Щільність коду також впливає на продуктивність; якщо ваші петлі довші, оскільки код не щільний, вам може знадобитися більше кешу інструкцій для утримання циклу. Більше кешу означає дорожчий процесор, але знову-таки складне декодування інструкцій означає більше транзисторів для розшифровки потрібної інструкції, тому це класична інженерна проблема.

ARM досить приємний в цьому відношенні. Кожна інструкція може бути умовною, більшість інструкцій може збільшувати або зменшувати значення регістрів, а більшість інструкцій додатково можуть оновлювати прапорці процесора. На ARM та з помірно корисним компілятором той самий цикл може виглядати приблизно так:

movl r0, count_bytes
movl r1, s
movl r2, d
loop: ldrb r3, [r1++]
strb [r2++], r3
subs r0, r0, 1
bne loop

Як бачите, зараз основним циклом є 4 інструкції. Код більш щільний, тому що кожна інструкція в основному циклі робить більше. Це, як правило, означає, що ви можете зробити більше із заданим обсягом пам’яті, оскільки менше цього використовується для опису того, як виконувати роботу.

Тепер рідний код ARM часто скаржився, що він не надто щільний; це пов'язано з двома основними причинами: по-перше, 32 біти - це жахливо "довга" інструкція, тому багато бітів, здається, витрачаються на простіші інструкції, а по-друге, код роздутий через характер ARM: кожна інструкція - 32 біти довгі, без винятку. Це означає, що існує велика кількість 32-бітних буквальних значень, які ви не можете просто завантажити в реєстр. Якщо я хотів завантажити "0x12345678" в r0, як я кодую інструкцію, яка не тільки містить 0x12345678, але також описує "завантажувати буквально r0"? Для кодування фактичної операції не залишилось бітів. Літеральна інструкція щодо завантаження ARM - це цікавий маленький звір, і збирач ARM також повинен бути трохи розумнішим, ніж звичайні асемблери, тому що він повинен "ловити"

У будь-якому випадку, щоб відповісти на ці скарги, ARM придумав режим Thumb. Замість 32 біт за інструкцію тепер довжина інструкції становить 16 біт для майже всіх інструкцій та 32 біт для гілок. У режимі великого пальця було кілька жертв, але за великим рахунком ці жертви було легко зробити, тому що Thumb отримав щось на зразок 40% -ного покращення щільності коду за рахунок зменшення довжини інструкції.


Відмінна відповідь. Дійсно чудово.
pingswept

Не забудьте згадати Thumb2, який є ще більшим вдосконаленням для більшості програм.
Янна Рамін

Дуже цікаво читати. Я багато чого вчусь, просто читаючи питання та відповіді на цьому сайті.
onaclov2000

Дуже дякую Ендрю, відмінна відповідь, це мені дуже допомогло з сумнівом :)
Quaremz

Це також може бути короткою згадкою про те, як на щільність коду впливає RISC проти CISC (при цьому RISC, як правило, нижчий за CISC, оскільки архітектури CISC мають більше інструкцій, які можуть робити більше, але можуть призвести до більш тривалих / складних конвеєрів, поки RISC орієнтована на більш прості інструкції, які дозволяють спростити трубопроводи, тому щільність коду RISC нижча).
JAB

1

"Щільність коду" набору інструкцій - це показник того, скільки речей ви можете потрапити в заданий об'єм пам'яті програми або скільки байтів програмної пам'яті потрібно для зберігання заданого обсягу функціональності.

Як зазначав Ендрю Колсміт, навіть у тому ж MCU різні компілятори можуть отримати різну щільність коду.

Можливо, вам сподобається читати "Комахи комп'ютерного світу" Миро Самека, який порівнює різні MCU.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.