Добавить в корзинуПозвонить
Найти в Дзене
Old Programmer

Ассемблер vs ассемблер (интрига не закончилась)

Программирование. Тематическое оглавление моего Zen-канала (Old Programmer). А здесь все по ассемблеру. Ранее в статьях (assembler vs C) Я пытался сравнивать производительность языка C и ассемблера, используя возможности оптимизации компилятора C. И надо сказать, что результат был хорош. Язык C почти нагнал ассемблер, но лишь почти. Но в целом я посчитал, что эксперимент удался. Однако в процессе обсуждения экспериментов, мне подсказали возможные варианты оптимизации уже ассемблерного кода. И я подумал, а почему бы ни по соревноваться ассемблеру с ассемблером. Оба исполняемых модуля основываются на одном и том же модуле (main200.c), но двух разных ассемблерных вставках (250.s и 250a.s). Трансляция программ осуществляется командами as --64 50.s -o 250.o
gcc -c main200.c
gcc -no-pie main200.o 250.o -o 200 и as --64 250a.s -o 250a.o
gcc -c main200.c
gcc -no-pie main200.o 250a.o -o 200a Оптимизация кода на языке ассемблера Теперь несколько слов о том, в чем же была суть попытки оптими
Оглавление

Весь Old Programmer здесь:
Программирование. Тематическое оглавление моего Zen-канала (Old Programmer). А здесь все по ассемблеру.

  • Список разделов канала Old Programmer, канала о программировании и программистах

Ранее в статьях (assembler vs C)

  • Ассемблер и C, пример эксперимента по сравнению производительности (начало интриги)
  • Ассемблерный код программ на языке C (интрига продолжается)
  • Ассемблерный код программ на языке C (интрига близка к завершению)
  • Ассемблер и C (конец интриги?)

Я пытался сравнивать производительность языка C и ассемблера, используя возможности оптимизации компилятора C. И надо сказать, что результат был хорош. Язык C почти нагнал ассемблер, но лишь почти. Но в целом я посчитал, что эксперимент удался. Однако в процессе обсуждения экспериментов, мне подсказали возможные варианты оптимизации уже ассемблерного кода. И я подумал, а почему бы ни по соревноваться ассемблеру с ассемблером.

Оба исполняемых модуля основываются на одном и том же модуле (main200.c), но двух разных ассемблерных вставках (250.s и 250a.s). Трансляция программ осуществляется командами

as --64 50.s -o 250.o
gcc -c main200.c
gcc -no-pie main200.o 250.o -o 200

и

as --64 250a.s -o 250a.o
gcc -c main200.c
gcc -no-pie main200.o 250a.o -o 200a

Оптимизация кода на языке ассемблера

Теперь несколько слов о том, в чем же была суть попытки оптимизировать ассемблерный код. Для этого нужно сравнить модули 250.s и 250a.s. Был убран инкремент rbx и суммирование по сути происходит с конца массива к началу. Суть в том, что loop все равно делает декремент rcx, в этом и есть суть алгоритма. Несколько усложнилась команда сложения, здесь, собственно и нужно было проверить, дает ли такое изменение положительный (оптимизационный) результат.

И так каждый из двух исполняемых модулей многократно (1000 раз) выполняется с помощью утилиты time с ключом -p и заносит результат в текстовый файл. Для каждого выполнения выводятся три временных интервала: real - общее время, user - время выполнения пользовательского кода вне ядра, sys - время потраченное на уровне ядра. Соответственно, затем скрипт суммирует и вычисляет среднее для каждого из времен для каждой из двух программ.

Полученный результат до конца мне не понятен. Я несколько раз его перепроверил, но он остался практически тем же.

Для модуля 250.s:
0.029910000000000332 0.007569999999999891 0.01721999999999976

Для модуля 250a.s:
0.03024000000000034 0.0072299999999998945 0.017829999999999763

Понятно, что оптимизация дала свои результаты, но почему это привело к увеличению системного времени, остается для меня загадкой. Но я думаю, что с вашей помощью загадка будет разрешена.

Подписываемся на мой канал Old Programmer и экспериментируем со своим кодом, это интересно.

Фрагмент программы 250a.s
Фрагмент программы 250a.s