[Ненормальное программирование, Assembler] Benchmark CPU's Instructions (just before loading the OS) — XCHG vs XOR, XOR, XOR
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
1.225.000 - среднее для XCHG (слева), 1.280.014 - среднее для XOR, XOR, XOR (справа)Возможно не только мне интересно, а каков микрокод инструкции XCHG на RISC для x86 CISC?Например ни для кого не секрет, что на языках высокого уровня, чтобы обменять значениями две переменные "X" и "Y", нужна ещё одна переменная, скажем "Z".
X=5, Y=7
Z=Y
Y=X
X=Z
X=7, Y=5
Но, процессоры это умеют делать командой XCHG, причём, явно никакой третьей переменной здесь вроде бы как и нет...
X=5, Y=7
XCHG X, Y
X=7, Y=5
Я даже предполагал что сама аббревиатура "XCHG", это ни что иное как "XOR CHANGE", сразу скажу что подтверждения этой догадки я нигде не встречал. Почему XOR CHANGE? Возможно потому что обмен между регистрами происходит с участием логической команды XOR.
X=5, Y=7
XOR X, Y
XOR Y, X
XOR X, Y
X=7, Y=5
Что ж, я решил проверить свою теорию, промерив продолжительность исполнения инструкции "XCHG" и её аналога "XOR, XOR, XOR". Ну а чтобы результаты были максимально детерминированными, я решил запустить всё это дело ещё до загрузки какой-либо операционной системы, т.е. сразу после того, как БИОС компьютера решит загружаться с определённого накопителя. В общем для максимальной чистоты эксперимента, я разместил приведённый ниже код прямо в MBR загрузочного диска (в своём случае я использовал флешку).
Следующий код повторяет инструкцию "XCHG EDI, EAX" 7 раз, а инструкцию "XOR" - 21 раз ну и накапливает затраченные тики процессора. Цикл для каждой тестируемой команды повторяется по 10000 раз. После чего всё это прокручивается ещё и ещё (всего 20 раз), в итоге вычисляется среднее. Как по мне, тест получается довольно "чистый", более-менее детерминированный. Ну а что касается того, равны ли по продолжительности исполнения команда XCHG и три команды XOR, то судя по этому тесту, XCHG выполняется на 5% быстрее, что никак не вписывается в мою теорию :)
до этого момента инициализация сегментных регистров + возможные перемещения блоков кода
mov ax, 3
int 10h
cli ; запретим прерывания
mov al, 0FFh
out 021h, al
out 0A1h, al
mov cx, 20 ; сделаем 20 попыток
again: push cx
xor ebp, ebp
mov si, 10000 ; повторим 10000 раз для XCHG
@@: xor eax, eax
xor edi, edi
cpuid ; заставим ЦПУ выполнить все предыдущие команды
rdtsc
rept 7 { xchg edi, eax } ; повторим 7 раз XCHG
cpuid
rdtsc
sub eax, edi ; вычтем разницу
add ebp, eax ; суммируем результаты
dec si
jnz @B
mov [_xchg], ebp
xor ebp, ebp
mov si, 10000 ; повторим 10000 раз для XOR
@@: xor eax, eax
xor edi, edi
cpuid
rdtsc
rept 7 { xor edi, eax ; повторим 7 раз по три XOR
xor eax, edi
xor edi, eax }
cpuid
rdtsc
sub eax, edi
add ebp, eax
dec si
jnz @B
next: mov [_xor], ebp
mov eax, [_xchg]
add [totalxchg], eax
mov di, [screen]
call print
add word [screen], 32
mov eax, [_xor]
add [totalxor], eax
mov di, [screen]
call print
add word [screen], 128
pop cx
dec cx
jnz again
dec byte [color+1]
mov eax, [totalxchg]
mov ebx, 20
xor edx, edx
idiv ebx
mov di,[screen]
call print
mov eax, [totalxor]
mov ebx, 20
xor edx, edx
idiv ebx
add word [screen], 32
mov di,[screen]
call print
@@: jmp @B ; на этом всё.
print: mov ebx, 10 ; подпрограмма вывода полученных значений на экран
xor cx, cx
more: mov si, bufferdec+12
xor edx, edx
sub si, cx
idiv ebx
add dl, '0'
mov [si], dl
inc cx
test cl, 1
je @F
test cl, 2
je @F
or eax, eax
je @F
mov [si-1], byte '.'
inc cx
@@: or eax, eax
jne more
color: mov ah, 7
push 0b800h
pop es
mov si, bufferdec+12
add di, cx
add di, cx
std
@@: lodsb
stosw
loop @b
push cs
pop es
ret
screen: dw 0
_xchg: dd 0
totalxchg: dd 0
_xor: dd 0
totalxor: dd 0
bufferdec: db 12 dup 0
rb 510 - ($ - $$)
db 55h,0AAh
===========
Источник:
habr.com
===========
Похожие новости:
- [Системное администрирование, Системное программирование, Сетевые технологии, API] Как использовать REST и SOAP API в Zimbra OSE
- [C++, Системы сборки] PVS-Studio Team: Switching to Clang Improved PVS-Studio C++ Analyzer's Performance
- [Assembler] Туториал по FASM (Windows x32 API/Win32API), «Hello world!»
- [Системное администрирование, Сетевые технологии, Хранение данных, Финансы в IT] Как посчитать окупаемость при внедрении Zextras Suite
- [Ненормальное программирование, *nix, C, Разработка под Linux] Внутренности Linux: как /proc/self/mem пишет в недоступную для записи память (перевод)
- [ВКонтакте API, GitHub, Тестирование веб-сервисов] Бенчмарки VKUI и других ребят из UI-библиотек
- [Ненормальное программирование, Usability, ECM/СЭД, Управление проектами, Подготовка технической документации] АнтиBIMing
- [Ненормальное программирование, Компиляторы] M/o/Vfuscator2, безумный компилятор
- [Анализ и проектирование систем, Assembler, Программирование микроконтроллеров] Сравнение векторных расширений ARM и RISC-V (перевод)
- [Системное администрирование, Сетевые технологии] Делегирование почтовых папок и отправки писем в Zimbra OSE
Теги для поиска: #_nenormalnoe_programmirovanie (Ненормальное программирование), #_assembler, #_xchg, #_xor, #_benchmark, #_speed, #_mbr, #_nenormalnoe_programmirovanie (
Ненормальное программирование
), #_assembler
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:55
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
1.225.000 - среднее для XCHG (слева), 1.280.014 - среднее для XOR, XOR, XOR (справа)Возможно не только мне интересно, а каков микрокод инструкции XCHG на RISC для x86 CISC?Например ни для кого не секрет, что на языках высокого уровня, чтобы обменять значениями две переменные "X" и "Y", нужна ещё одна переменная, скажем "Z". X=5, Y=7 Z=Y Y=X X=Z X=7, Y=5 Но, процессоры это умеют делать командой XCHG, причём, явно никакой третьей переменной здесь вроде бы как и нет... X=5, Y=7 XCHG X, Y X=7, Y=5 Я даже предполагал что сама аббревиатура "XCHG", это ни что иное как "XOR CHANGE", сразу скажу что подтверждения этой догадки я нигде не встречал. Почему XOR CHANGE? Возможно потому что обмен между регистрами происходит с участием логической команды XOR. X=5, Y=7 XOR X, Y XOR Y, X XOR X, Y X=7, Y=5 Что ж, я решил проверить свою теорию, промерив продолжительность исполнения инструкции "XCHG" и её аналога "XOR, XOR, XOR". Ну а чтобы результаты были максимально детерминированными, я решил запустить всё это дело ещё до загрузки какой-либо операционной системы, т.е. сразу после того, как БИОС компьютера решит загружаться с определённого накопителя. В общем для максимальной чистоты эксперимента, я разместил приведённый ниже код прямо в MBR загрузочного диска (в своём случае я использовал флешку). Следующий код повторяет инструкцию "XCHG EDI, EAX" 7 раз, а инструкцию "XOR" - 21 раз ну и накапливает затраченные тики процессора. Цикл для каждой тестируемой команды повторяется по 10000 раз. После чего всё это прокручивается ещё и ещё (всего 20 раз), в итоге вычисляется среднее. Как по мне, тест получается довольно "чистый", более-менее детерминированный. Ну а что касается того, равны ли по продолжительности исполнения команда XCHG и три команды XOR, то судя по этому тесту, XCHG выполняется на 5% быстрее, что никак не вписывается в мою теорию :) до этого момента инициализация сегментных регистров + возможные перемещения блоков кода
mov ax, 3 int 10h cli ; запретим прерывания mov al, 0FFh out 021h, al out 0A1h, al mov cx, 20 ; сделаем 20 попыток again: push cx xor ebp, ebp mov si, 10000 ; повторим 10000 раз для XCHG @@: xor eax, eax xor edi, edi cpuid ; заставим ЦПУ выполнить все предыдущие команды rdtsc rept 7 { xchg edi, eax } ; повторим 7 раз XCHG cpuid rdtsc sub eax, edi ; вычтем разницу add ebp, eax ; суммируем результаты dec si jnz @B mov [_xchg], ebp xor ebp, ebp mov si, 10000 ; повторим 10000 раз для XOR @@: xor eax, eax xor edi, edi cpuid rdtsc rept 7 { xor edi, eax ; повторим 7 раз по три XOR xor eax, edi xor edi, eax } cpuid rdtsc sub eax, edi add ebp, eax dec si jnz @B next: mov [_xor], ebp mov eax, [_xchg] add [totalxchg], eax mov di, [screen] call print add word [screen], 32 mov eax, [_xor] add [totalxor], eax mov di, [screen] call print add word [screen], 128 pop cx dec cx jnz again dec byte [color+1] mov eax, [totalxchg] mov ebx, 20 xor edx, edx idiv ebx mov di,[screen] call print mov eax, [totalxor] mov ebx, 20 xor edx, edx idiv ebx add word [screen], 32 mov di,[screen] call print @@: jmp @B ; на этом всё. print: mov ebx, 10 ; подпрограмма вывода полученных значений на экран xor cx, cx more: mov si, bufferdec+12 xor edx, edx sub si, cx idiv ebx add dl, '0' mov [si], dl inc cx test cl, 1 je @F test cl, 2 je @F or eax, eax je @F mov [si-1], byte '.' inc cx @@: or eax, eax jne more color: mov ah, 7 push 0b800h pop es mov si, bufferdec+12 add di, cx add di, cx std @@: lodsb stosw loop @b push cs pop es ret screen: dw 0 _xchg: dd 0 totalxchg: dd 0 _xor: dd 0 totalxor: dd 0 bufferdec: db 12 dup 0 rb 510 - ($ - $$) db 55h,0AAh =========== Источник: habr.com =========== Похожие новости:
Ненормальное программирование ), #_assembler |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:55
Часовой пояс: UTC + 5