0 / 0 / 0
Регистрация: 10.04.2016
Сообщений: 9
|
||||||||||||||||
FASM Оптимизации при компиляции gcc в ассемблерный код27.03.2019, 01:31. Показов 6182. Ответов 17
На лабораторную работу нам задали написать свой простейший транслятора си-подобного языка в ассемблерный код. Для этого я выбрал fasm и пока что доволен. Поскольку я совсем не силен в ассемблерном программировании, для написания кода подсматриваю нужные директивы на сайте godbolt, который позволяет посмотреть ассемблерный код, генерируемый разными компиляторами. Я заметил, что при использовании локальных переменных они помещаются в stack не подряд, а с выравниванием к нужному количеству байт. Например, при использовании кода:
Собственно мой вопрос: почему так делается, неужели так быстрее? Или это просто из-за простоты? При написании лабораторной, следует мне делать так же, или всё же использовать
0
|
27.03.2019, 01:31 | |
Ответы с готовыми решениями:
17
Ошибка при компиляции в WinAvr GCC
|
![]() 1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
|
|||
27.03.2019, 01:48 | |||
1
|
4179 / 1828 / 219
Регистрация: 06.10.2010
Сообщений: 4,117
|
||
27.03.2019, 12:59 | ||
1
|
Asm/C++/Delphi/Py/PHP/VBA
![]() |
||||
28.03.2019, 14:25 | ||||
Если интересует оптимизация, есть хороший мануал по этому делу: https://www.agner.org/optimize... sembly.pdf Да и вообще тут много других интересных вещей можно найти ![]() Добавлено через 1 час 7 минут По умолчанию для арифметики используются 32-битные регистры, а для адресации – 64-битные. Чтобы изменить разрядность, ставится префикс (REX-префикс и 67h соответственно). Поэтому инструкция mov eax,[rdx] будет на 2 байта короче, чем mov rax,[edx] (последняя будет одинаковой длины с mov ax,[edx] ) ![]() Далее, при записи в 32-битный регистр (любой операцией, хоть mov , хоть add , хоть shr ) обнуляется старшая часть соответствующего 64-битного регистра. Поэтому вместо movzx rax,eax (такой формы инструкции просто нет) делается mov eax,eax ![]()
1
|
Эксперт Hardware
![]() ![]() |
|||
28.03.2019, 15:48 | |||
и непонятно, почему она не ругается на твою строку mov BYTE PTR [rbp-1], 2 в доках интела vol.3A есть такое описание:
..сорян, это-же RBP поэтому видимо можно, а RSP нельзя. хотя в любом случае стек получается невыровненным.
1
|
Asm/C++/Delphi/Py/PHP/VBA
![]() |
||
28.03.2019, 21:34 | ||
1
|
Эксперт Hardware
![]() ![]() |
||
28.03.2019, 23:58 | ||
хотя выравнивание в секции-данных даёт выигрыш в скорости, т.к. требует на границах параграфа один/шинный цикл, а невыровненные данные - два цикла (можно попробовать снять профайл, при чтении/записи больших объёмов данных).
2
|
Эксперт Hardware
![]() ![]() |
|
30.03.2019, 09:41 | |
Выравнивать данные меньше чем на 8-байт смысла нет, и вот почему..
Процессор и память связывает 64-битная шина, т.е. в любом случае минимальной порцией обмена является 8-байт. Но в большинстве случаях обмен происходит в пакетном режиме, с "Burst_Length" равным 8 (кол-во авто/повторов BL=8) - итого получаем 8*8=64 байт, которые сохраняются в кэш-памяти процессора как "64-byte cache_line". Таким образом, выставляемый процессором на шину адрес, всегда получается кратным 64 (младшие 6-бит обнуляются). Шинный цикл - это число тактов от момента передачи адреса, до получения данных процессором (сумма таймингов памяти). На транспорт 64-байтного пакета расходуется всего 1 шинный-цикл, но только если начальный адрес пакета выровнен на 8-байтную границу! Посмотрим на скрин ниже: ![]() Допустим, мы запросили выделенный жёлтым dword с адреса 013Eh.. Поскольку адрес процессора кратен 64, то он выставит на шину адрес 0100h, и в пакетном режиме считает в свой кэш весь/выделенный "морской волной" блок в диапазоне 0100-013F - на это уйдёт один шинный цикл. Но мы запросили dword, и старшее его слово вышло за пределы 64-байтной кэш-строки. Значит процессору придётся взять в свой кэш следующий блок с адреса 0140h, на что потребуется ещё один цикл-чтения. А вот если-бы наш dword был выровнен на 8-байтную границу, то он в любом случае попал-бы в диапазон - или в первую кэш-линейку, или во-вторую. То-есть считался-бы за один шинный цикл.
2
|
Asm/C++/Delphi/Py/PHP/VBA
![]() |
|
30.03.2019, 12:13 | |
2
|
Эксперт Hardware
![]() ![]() |
||
30.03.2019, 13:38 | ||
т.е. для х32 можно и на 4 выравнить, а для 8-байтных регистров х64, четвёрки уже не хватит.
1
|
Asm/C++/Delphi/Py/PHP/VBA
![]() |
|||
30.03.2019, 13:58 | |||
![]()
1
|
Эксперт Hardware
![]() ![]() |
|
30.03.2019, 14:26 | |
Да вообще, в наш век с многоядерными процессорами и тоннами кэша, предвыборкой и предсказанием переходов - проблемы оптимизации кода не существует в принципе. Это было актуально для вторых/третьих поколений машин, а сейчас уже за восьмое перевалил. Это бородатые преподы никак не могут расстаться со-своим прошлым, и тянут туда-же студней.
1
|
Asm/C++/Delphi/Py/PHP/VBA
![]() |
|||||||||||
30.03.2019, 16:38 | |||||||||||
R71MT, не соглашусь. Нюансов оптимизации полно и сейчас. Начиная от
sub ecx,1 + jnz vs loop , продолжая выравниванием (оно всё же имеет значение) и заканчивая выбором инструкций для отдельных вещей (тут много примеров). Перестановка не всегда поможет, элементарно:
1
|
Эксперт Hardware
![]() ![]() |
|
31.03.2019, 10:38 | |
Я хочу сказать, что современный процессор даже не будет пытаться что-то заменить в примере выше (этим должен заниматься компилятор) - процессор выполнит в 2-раза больше простых инструкций всего за один такт, поскольку сейчас у него не парочка, а 8..16 исполнительных блоков ALU (не считая скалярных, см.Skylake), ..плюс 48 штук у GPU (см.Gen11). Причём работают эти блоки - параллельно!
Если коротко, то современное "Оut-оf-Оrder" ядро является гибридным и включает в себя блоки как "внеочередного", так и "спекулятивного" исполнения команд. Процессор не исполняет инструкции последовательно, и пока занимается текущей, в фоне обрабатывает сразу и последующие (из кэша-инструкций). Если у этих/последующих готовы все операнды, то такие инструкций внеочереди отправляются в свободный порт (см.скрин ниже), который связан с исполнительным блоком ALU/FPU. Если-же операнды не готовы, то инструкция откладывается до лучших времён и ждёт, пока до неё дойдёт указатель CS:EIP. Бонусом идёт и спекулятивное исполнение, когда в добавок к беспорядочной очереди добавляются алгоритмы прогнозирования. Суть в том, что на основе уже выполненных инструкций, процессор старается предсказать и заранее выполнить действие ещё до того, как будет получена соответствующая инструкция. Как упоминалось выше, в одном ядре процессора в среднем могут быть 10 портов. Прибавим к этому наличие нескольких ядер под одним колпаком процессора, и получим монстра, которому оптимизация в несколько байт на уровне инструкций - абсолютно по-барабану. Оптимизация кода была актуальна для процессоров до i486 (Am5) включительно. Дальше, микроархитектура мутировала - к имеющийся CISC добавили RISC c основным нововведением "Декодер инструкций" (до 486 его не было). Именно декодер разбивает наши инструкции на упрощённые RISC, которые можно выполнять параллельно сразу на нескольких ALU. Теперь у процессора есть своя/внутренняя система команд, не имеющая ничего общего с теми инструкциями, которые поступают извне. Поэтому сколько-бы мы не потратили сил на оптимизацию кода в своих программах, ядро процессора всё-равно проигнорирует наш план, т.к. работает по своим/аппаратным правилам, которые мы не в силах изменить. (хотя вмешаться в эти правила конечно-же можно, если добраться до "MicroOps-ROM", где хранятся RISC-инструкции). Единственным условием оптимизации в современных процессорах является код, который использует смешанные с FPU инструкции, т.к. исполняющие блоки внутри ядра у них разные - для ALU свои, для FPU свои и они по-большей части простаивают.
2
|
Asm/C++/Delphi/Py/PHP/VBA
![]() |
|
31.03.2019, 21:24 | |
1
|
Эксперт Hardware
![]() ![]() |
||
01.04.2019, 11:37 | ||
помоему на хабре когда-то была статья, где чел путешествовал внутрь процика..
вот цитата от из этой статьи:
1
|
Эксперт Hardware
![]() ![]() |
|
01.04.2019, 11:46 | |
последний рисунок - это микро/архитектура NetBurst четвёртого пенька.
1
|
01.04.2019, 11:46 | |
Помогаю со студенческими работами здесь
18
При компиляции на Dev прога пашет, а на gcc нет. Ошибки при компиляции ClanLib с помощью GCC(MinGW) 4.6.2
При компиляции с помощью gcc или llvm, происходит ошибка и они требуют амперсанд Перевести ассемблерный код TASM в программный код для архитектуры ARM Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Опции темы | |
|
Новые блоги и статьи
![]() |
||||
Blazor и контроллер сервопривода IoT Meadow Maple
Wired 11.07.2025
Я решил разобраться, как можно соединить современные веб-технологии с миром "железа". Интересная комбинация получилась из Blazor в качестве веб-интерфейса и микроконтроллера Meadow с его веб-сервером. . .
|
Генерация OpenQASM из кода Q#
EggHead 10.07.2025
Летом 2024-го я начал эксперименты с библиотекой Q# Bridge, и знаете что? Она оказалась просто находкой для тех, кто работает на стыке разных квантовых экосистем. Основная фишка этой библиотеки -. . .
|
Изучаем новый шаблон ИИ-чата .NET AI Chat Web App
stackOverflow 10.07.2025
В . NET появилось интересное обновление - новый шаблон ИИ-чата под названием . NET AI Chat Web App. Когда я впервые наткнулся на анонс этого шаблона, то сразу понял, что Microsoft наконец-то. . .
|
Результаты исследования от команды ARP (июль 2025 г.)
Programma_Boinc 10.07.2025
Результаты исследования от команды ARP (июль 2025 г. )
Африканский проект по дождям (ARP) World Community Grid снова запущен! Мы рады поделиться обновленной информацией о нашем прогрессе с осени. . .
|
Angular vs Svelte - что лучше?
Reangularity 09.07.2025
Сегодня рынок разделился на несколько четких категорий: тяжеловесы корпоративного уровня (Angular), гибкие универсалы (React), прогрессивные решения (Vue) и новая волна компилируемых фреймворков. . .
|
Code First и Database First в Entity Framework
UnmanagedCoder 09.07.2025
Entity Framework дает нам свободу выбора, предлагая как Code First, так и Database First подходы. Но эта свобода порождает вечный вопрос — какой подход выбрать?
Entity Framework — это. . .
|
Как использовать Bluetooth-модуль HC-05 с Arduino
Wired 08.07.2025
Bluetooth - это технология, созданная чтобы заменить кабельные соединения. Обычно ее используют для связи небольших устройств: мобильных телефонов, ноутбуков, наушников и т. д. Работает она на частоте. . .
|
Руководство по структурам данных Python
AI_Generated 08.07.2025
Я отчетливо помню свои первые серьезные проекты на Python - я писал код, он работал, заказчики были относительно довольны. Но однажды мой наставник, взглянув на мою реализацию поиска по огромному. . .
|
Тестирование энергоэффективности и скорости вычислений видеокарт в BOINC проектах
Programma_Boinc 08.07.2025
Тестирование энергоэффективности и скорости вычислений видеокарт в BOINC проектах
Опубликовано: 07. 07. 2025
Рубрика: Uncategorized
Автор: AlexA
Статья размещается на сайте с разрешения. . .
|
Раскрываем внутренние механики Android с помощью контекста и манифеста
mobDevWorks 07.07.2025
Каждый Android-разработчик сталкивается с Context и манифестом буквально в первый день работы. Но много ли мы задумываемся о том, что скрывается за этими обыденными элементами? Я, честно говоря,. . .
|