Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.06.2015, 11:00   #1
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
Вопрос Как работает XCHG (изнутри)?

ASM-вставка на Delphi XE5. Есть 2 варианта кода:
#1
Код:
        MOV      EBX , [EAX]
        XCHG    [EDX],  EBX
        MOV     [EAX],  EBX
#2
Код:
        PUSH    [EAX] 
        MOV      EBX,  [EDX]
        MOV     [EAX],  EBX
        POP     [EDX]
Результат у них одинаковый. Интуитивно я предполагал, что #1 будет работать быстрее (ну уж точно не медленнее). А по факту #2 ~ в 4 раза быстрее чем #1.

Подскажите, почему так происходит?
Sibedir вне форума Ответить с цитированием
Старый 05.06.2015, 11:25   #2
AbakBarama
Пользователь
 
Регистрация: 12.05.2011
Сообщений: 57
По умолчанию

А замерам производительности можно доверять? Без тестирования, рассуждая только теоретически, я бы тоже высказался в пользу #1.

P. S. Еще вспомнилось, что команда XCHG использует какую-то дополнительную блокировку, вроде бы даже аппаратную, дабы между чтением из памяти и записью в память никто не встрял. Возможно, в этом дело?
AbakBarama вне форума Ответить с цитированием
Старый 05.06.2015, 12:13   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Там при регистр-память тактов не меньше 15 или 18 (точно не помню)
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 05.06.2015, 12:20   #4
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
Сообщение от AbakBarama Посмотреть сообщение
А замерам производительности можно доверять?
Не знаю. Наверное. Меня профессионалом в программировании только этот форум и считает (люблю его за это нЯшка)
Код:
procedure PUSH_POP (A, B: PInteger);
asm
  MOV      ECX, $0FFFFFFF
@@begin:
  PUSH    [EAX]
  MOV      EBX,  [EDX]
  MOV     [EAX],  EBX
  POP     [EDX]
  LOOP    @@begin
end;

procedure XCHG (A, B: PInteger);
asm
  MOV      ECX, $0FFFFFFF
@@begin:
  MOV      EBX , [EAX]
  XCHG    [EDX],  EBX
  MOV     [EAX],  EBX
  LOOP    @@begin
end;

procedure TfrmMain.Button4Click(Sender: TObject);
var
  x, y: Integer;
  b, e1, e2: Cardinal;
begin
  x := 1;
  y := 2;

  b := GetTickCount;
  PUSH_POP (@x, @y);
  e1 := GetTickCount - b;

  b := GetTickCount;
  XCHG (@x, @y);
  e2 := GetTickCount - b;

  ShowMessage ('e1 = ' + IntToStr(e1) + #13 +
               'e2 = ' + IntToStr(e2));
end;
Цитата:
P. S. Еще вспомнилось, что команда XCHG использует какую-то дополнительную блокировку, вроде бы даже аппаратную, дабы между чтением из памяти и записью в память никто не встрял. Возможно, в этом дело?
Блокировку? Ссылки какой нет, случайно?
Sibedir вне форума Ответить с цитированием
Старый 05.06.2015, 12:33   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

http://www.google.com.ua/search?hl=r....0.H_plAF8xAYs
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 05.06.2015, 13:02   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Там при регистр-память тактов не меньше 15 или 18 (точно не помню)
Так стек же - это тоже память

Даже эта хрень работает быстрее
Код:
procedure Foo (A, B, C: PInteger);
asm
  MOV      EBX,  ECX
  MOV      ECX, $0FFFFFFF
@@begin:
  PUSH     ECX
  MOV      ECX , [EAX]
  MOV     [EBX],  ECX
  MOV      ECX , [EDX]
  MOV     [EAX],  ECX
  MOV      ECX,  [EBX]
  MOV     [EDX],  ECX
  POP      ECX
  LOOP    @@begin
end;
Цитата:
Сообщение от Аватар Посмотреть сообщение
Цитата:
Сообщение от AbakBarama Посмотреть сообщение
P. S. Еще вспомнилось, что команда XCHG использует какую-то дополнительную блокировку, вроде бы даже аппаратную, дабы между чтением из памяти и записью в память никто не встрял. Возможно, в этом дело?
Спасибо, ребят.

Последний раз редактировалось Sibedir; 05.06.2015 в 13:07.
Sibedir вне форума Ответить с цитированием
Старый 05.06.2015, 13:10   #7
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
b := GetTickCount;
Для ассемблерных тестов у GetTickCount слишком маленькое разрешение. Только QueryPerformanceCounter, только хардкор!

Цитата:
Сообщение от Sibedir Посмотреть сообщение
Блокировку? Ссылки какой нет, случайно?
Блокировку. Ссылка где-то в доке Intel или AMD, видимо. Даже если второй вариант и с QueryPerformanceCounter будет быстрее, на деле две ассемблерные вставки делают разное (с точки зрения ассемблера): c XCHG -- более-менее согласованный обмен, а с двумя MOV -- ничего не гарантирующий, пригодный только для однопоточных программ.
Vapaamies вне форума Ответить с цитированием
Старый 05.06.2015, 13:19   #8
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
... с двумя MOV -- ничего не гарантирующий, пригодный только для однопоточных программ.
Да. Так оно и нужно. Однопоточная обработка массива данных.

Цитата:
Для ассемблерных тестов у GetTickCount слишком маленькое разрешение.
При $0FFFFFFF повторах волне себе явно проявляются различия. Да не. Думаю не в этом дело.

Последний раз редактировалось Sibedir; 05.06.2015 в 13:22.
Sibedir вне форума Ответить с цитированием
Старый 05.06.2015, 14:43   #9
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

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

зы. можешь еще с MOVNTI [eax], ebx сравнить.

Последний раз редактировалось f.hump; 05.06.2015 в 14:50.
f.hump вне форума Ответить с цитированием
Старый 06.06.2015, 12:15   #10
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Цитата:
Сообщение от f.hump Посмотреть сообщение
в мануале ж все есть.
Ага, есть Я только здесь нашел: x86 Architecture.
А вот здесь x86 Instructions, как это ни странно, об это ни слова.
Вотжиш люди.
Цитата:
Сообщение от x86 Architecture
...
The xchg instruction automatically obeys the previous rules whenever it exchanges a value with memory.
All other instructions default to nonlocking.
Тоесть в описании единственной autolocking инструкции об это её свойстве ни слова. Кстати, в остальных источниках, которые я использовал (онлайн, пара книг), это тоже явно не указано в описании самой инструкции. Вот у Зубкова С.В. это напивано в описании инструкции LOCK. Так не честно

Последний раз редактировалось Sibedir; 06.06.2015 в 12:28.
Sibedir вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание игры - взгляд изнутри (дневник разработки и учебное пособие) Гром Gamedev - cоздание игр: Unity, OpenGL, DirectX 97 15.01.2017 14:31
5 колонна разрушит Россию изнутри challengerr Свободное общение 22 11.06.2014 13:48
дельфи изнутри. ромик0 Помощь студентам 8 16.01.2012 13:36
статья - Может-ли ПО работать быстрее или взгляд изнутри Pblog Обсуждение статей 0 27.02.2011 23:10
[Вопросы]Работа с процессами. Процессы изнутри Человек_Борща Общие вопросы Delphi 2 03.04.2010 18:37