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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 07.11.2015, 17:49   #1
alcaedo
Пользователь
 
Регистрация: 05.09.2015
Сообщений: 28
По умолчанию Чтение из памяти в обратном порядке

Код:
        MOV EAX,[R11+00] ; ROL EAX,16 ; XOR EAX,[R12+28] ; JNZ @N1neN2s1
        MOV EAX,[R11+04] ; ROL EAX,16 ; XOR EAX,[R12+24] ; JNZ @N1neN2s1
        MOV EAX,[R11+08] ; ROL EAX,16 ; XOR EAX,[R12+20] ; JNZ @N1neN2s1
        MOV EAX,[R11+12] ; ROL EAX,16 ; XOR EAX,[R12+16] ; JNZ @N1neN2s1
        MOV EAX,[R11+16] ; ROL EAX,16 ; XOR EAX,[R12+12] ; JNZ @N1neN2s1
        MOV EAX,[R11+20] ; ROL EAX,16 ; XOR EAX,[R12+08] ; JNZ @N1neN2s1
        MOV EAX,[R11+24] ; ROL EAX,16 ; XOR EAX,[R12+04] ; JNZ @N1neN2s1
        MOV EAX,[R11+28] ; ROL EAX,16 ; XOR EAX,[R12+00] ; JZ  @N1eqN2
  @N1neN2s1:                        // [R11]^s1 <> [R12]
Это кусок кода из середины ассемблерной функции Delphi. Точки с запятой, если кто не в курсе, просто разделяют команды, а не обозначают начало комментария. В R11 и в R12 находятся адреса некоторых 32-байтных полей. Эти поля могут следовать одно сразу за другим, а могут быть разнесены в памяти на большое расстояние, вплоть до 2-х гигабайт. Единственное, что гарантируется: R11<R12.

Вопрос в том, как оптимально задействовать кэш процессора при таком чтении. Из кода видно, что либо первое поле, либо второе в любом случае придётся читать в обратном направлении. Как я понимаю, с адреса [R11] в кэш будут прочитаны сразу несколько байт на опережение, а с R12 каждый раз будет идти обращение к ОЗУ. Может есть какая-то команда, которая загрузит второе поле в кэш с самого начала? Ну, и вообще, возможно ли тут получить какой-то прирост в производительности?
alcaedo вне форума Ответить с цитированием
Старый 08.11.2015, 12:49   #2
Мордохвост
Пользователь
 
Регистрация: 15.04.2015
Сообщений: 30
По умолчанию

В целом можно подчерпнуть в Optimizing subroutines in assembly language by Agner Fog.
ROL 16 это ведь как псевдо "bswap ax ; bswap eax ; bswap ax", тогда я вроде корректно сделал пшафл. У меня получилось лишь в 2 раза формально(читай: синтетически) ускорить через sse, набросок:
Код:
procedure Experimental(const AddrR11, AddrR12:Pointer);
asm
  push      r12
  mov       r11,rcx
  mov       r12,rdx
  mov       ecx,100

@@loop:
  movdqu    xmm0,[r11+00]  
  movdqu    xmm1,[r12+16] 
  pshuflw   xmm0,xmm0,$B1
  pshufhw   xmm0,xmm0,$B1
  pxor      xmm0,xmm1
  ptest     xmm0,xmm0
  jnz       @@found1
  movdqu    xmm0,[r11+16]
  movdqu    xmm1,[r12+00]
  pshuflw   xmm0,xmm0,$B1
  pshufhw   xmm0,xmm0,$B1
  pxor      xmm0,xmm1
  ptest     xmm0,xmm0
  jnz       @@found2
  sub       ecx,1
  jg        @@loop
  jmp       @@exit

@@found2:
  //do something

@@found1:
  //do something

@@exit:
  pop       r12
end;
Код:
...
SetLength(AR11,1000);
SetLength(AR12,1000);
for i := 0 to 999 do
  begin
    AR11[i] := $01020304;
    AR12[i] := $03040102;
  end;

t1 := MIRDTSC;
for i := 0 to 999 do
begin
  Experimental(Pointer(@AR11[0]),Pointer(@AR12[0]));
end;
t2 := MIRDTSC;

Result := t2 - t1;
...
Структуры или что там в r11/r12 якобы будем считать уже адаптированы под такое. Есть ещё хинт для проца "prefetcht0 [rcx]" ( в rcx адресс че нужно прокэшировать для чтения), но эта штука раз на раз не приходится.
Мордохвост вне форума Ответить с цитированием
Старый 08.11.2015, 18:32   #3
alcaedo
Пользователь
 
Регистрация: 05.09.2015
Сообщений: 28
По умолчанию

О! Я тоже в эту сторону посмотрел сегодня и вот, что получилось:
Код:
        MOVAPS  XMM0,[R11]
        MOVAPS  XMM1,[R12+$10]
        pshufd  xmm0,xmm0,$4E
        pshufhw xmm0,xmm0,$1B
        pshuflw xmm0,xmm0,$1B
        XORPS   xmm0,xmm1
        PTEST   xmm0,xmm0
        JNZ     @N1neN2s1
        MOVAPS  XMM0,[R11+$10]
        MOVAPS  XMM1,[R12]
        pshufd  xmm0,xmm0,$4E
        pshufhw xmm0,xmm0,$1B
        pshuflw xmm0,xmm0,$1B
        XORPS   xmm0,xmm1
        PTEST   xmm0,xmm0
        JZ      @N1eqN2
  @N1neN2s1: // [R11]^s1 <> [R12]
Все данные в программе выровнены на 16. А чем отличается XORPS от PXOR и чем MOVDQU от MOVAPS(MOVUPS)? У меня вышел выигрыш по времени до 6.2%. 6% получается только на массивах, которые по результату сравнения будут признаны эквивалентными. На случайно заполненных массивах разницы в скорости нет. На частично эквивалентных разница 0..6%. Но у меня большой расход времени на организацию цикла для теста, так что реальный выигрыш больше 6%.

Ещё немного покопался с разных статьях. Нашёл информацию о том, что данные из ОЗУ в кэш загружаются обычно пачками по 64 байта, выровненными на 64. Если так, то код из первого поста никак больше не улучшить. Там и там всё нормально кэшируется. Если второй массив весь умещается в такой выровненный на 64 блок из 64х байт, то при чтении последнего элемента массива, весь массив будет загружен в кэш. А если массив размазан на два блока, то в любом случае (для полного сравнения) придётся эти два блока загружать полностью из памяти.
alcaedo вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вывести символы в обратном порядке в оперативной памяти Oxidous Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 12.12.2015 12:45
Вывод из БД в обратном порядке Parallelogram PHP 10 22.05.2014 07:35
перестановка байтов в обратном порядке с++ Niklitel Помощь студентам 1 17.03.2014 09:10
Столбцы в обратном порядке Арианна Microsoft Office Excel 5 16.01.2014 06:05
В обратном порядке mari.ha Общие вопросы C/C++ 7 25.12.2008 21:36