Дополнения к "Архитектуре XX века"
21-10-2005 22:05
к комментариям - к полной версии
- понравилось!
Yury_Malich, известный профессионал в области устройства CPU, указал на несколько неточностей в моей теме номера (КТ #609). Для всех, кого статья заинтересовала - с любезного согласия Юры выкладываю список его замечаний к "Архитектуре XX" века:
Yury_Malich: Привет.
Хотел тебе кинуть несколько замечаний по статье про архитектуру CPU
1. оказалось сложно не только выполнять, но даже просто декодировать (выделять из машинного кода новую инструкцию и отправлять её на исполнительные устройства).
(Это не то чтобы вдруг оказалось :) : микрокод для сложных команд был с самого начала. Просто он имел несколько иную форму, чем у более поздних RISC-x86 ядер )
2. из-за «тормознутости» оперативной памяти тех времен «прошитые» в память процессора «расшифровки» сложных инструкций в виде последовательностей более простых команд, в какой-то момент стали работать медленнее
(напрашивается вопрос: если микрокод прошит в памяти процессора, то причём здесь «тормознутость оперативной памяти тех времен»?:) На самом деле микрокод работал медленнее по другой причине: из-за снижения темпа, что я покажу ниже на примере команды деления)
3. Да что там синус с косинусом - в некоторых RISC-процессорах разработчики пытались отказаться даже от использования трудно реализуемого аппаратного умножения деления (а вот здесь всё очень правильно IMHO. Микрокод команды деления (рассмотрю на примере вещественного) на несколько десятков тактов занимает часть блоков FPU отвечающих за сложение и умножения, что снижает темп, так как не позволяет выполнять независящие от неё операыии. И, если выполнять деление программно, то можно между цепочкой зависимых команд, выполняющих алгоритм деления, отпрапвлять на исполнение независимые команды умножения и сложения )! Правда, до таких крайностей ни один коммерческий RISC, (AFAIK деления нет во многих RISK-ах, например в Itanium) к счастью, не дошёл
4. Для сравнения: в классическом x86 IA-32 всего восемь регистров общего назначения, причем каждому из них приписано то или иное "специальное назначение" (скажем, в ESP хранится указатель на стек) затрудняющее или делающее невозможным его использование. (Ну это некорректно. :) Это не регистрам приписано "специальное назначение", это ряду непримитивных команд «приписаны регистры». Например те же самый PUSH , POP, CALL и RET – сложные команды декодируемые в несколько микроопрераций вполне могут быть заменены комбинацией простейших тривиальных команд MOV, ADD, JMP, для которых все регистры абсолютно равнозначны )
5. инструкций (лучше не инструкций а микроопераций :) ) за такт, а процессор Athlon 64 – девять. Реальные цифры, конечно, гораздо скромнее и определяются трудностью полноценной загрузки всех исполнительных устройств, однако Pentium 4 всё-таки способен исполнять в устоявшемся режиме две (в устоявшемся режиме именно 3 !, так как речь идёт в общем об инструкциях, а не о каких-то конкретных :) ) (при некоторых условиях - четыре) (не надо этой оговорки, так как она не относится к устоявшемуся режиму и инструкциям вообще. Темп чтения из TC -3 микрооперации за такт (6 за 2 такта), темп отставки – 3 микрооперации за такт – и там и там лимит устоявшегося режима. 4 микрооперации будут выполнены только в случае, если в одном из предыдущих тактов было выполнено 2 операции, и есть резерв в буфере отставки и достаточно команд в буфере планирвщика), а Athlon 64 – три инструкции за такт, одновременно производя две (у читателя создаётся ощущения, что две любые, а на самом деле только 1 чтения и одну записи ) (у A64 – три) (с 2 чтения или 2 записи или комбинацию 1 чтение,одна запись ) операции.
6. или одновременного исполнения нескольких «веток» программного кода в IA-64 (учитывая что предложение начиналось с «продвинутый» Scheduler, это здесь совершенно не к месту, так как в Itanium нет абсолютно никакого планирвщика и исполнения нескольких «веток» происходит исключительно благодаря заранее подготовленному компилятором коду)
7. инструкция сложения двух регистров SSE по 4 числа в каждом – декодером банально генерируется код из четырех независимых (ОШИБКА! SSE данные в обоих процессорах обрабатываются порцияами шириной 64 бита, то есть по 2 32 битных float за такт. Поэтому реально декодер K8 преобразует 1 SSE инструкцию в 2 микрооперации сложения 2 пар float. При этом Pentium 4 всё равно сгенерирует 1 мирооперацию, которая , правда, будет выпонятся на конвейере FPU последовательно над 64-битными половинками, как две отдельных в К8 )
8. Эффективная длина конвейера[Время в тактах от начала исполнения инструкции до момента, когда результаты выполнения будут записаны в оперативную память] Под эффективной длиной конвейера обычно понимают те стадии, на которых наблюдается задержка при сбросе конвейера при неправльно предсказанном переходе. А вот для с учётом момента когда будут записаны в оперативную память подлиннее будет :)
9. до полного зацикливания - deadlock’а!) Не надо пугать читателей, а то они подумаю, что процессор правда зависает :). Deadlock – это больше теоретический момент работы репеея. Если он и случается жизни, то процессор быстро с ним справляется, не заметно для пользователя.
Надеюсь, что эти замечания будут интересны не только мне :).
вверх^
к полной версии
понравилось!
в evernote