Project

General

Profile

Программирование на ассемблере. Пара вопросов о производительности

Added by qewerty over 10 years ago

Вот допустим есть функция перемножения матриц 4 на 4 (указатели на стек и фрейм не меняются, т.к. локальные переменные на стеке не нужны). Матрицы хранятся по столбцам (как в OpenGL).

.global qf_mat44_mul
qf_mat44_mul:
    .alias qf_mat44_mul.a #SP,4
    .alias qf_mat44_mul.b #SP,8
    .alias qf_mat44_mul.c #SP,12

    jmp qf_mat44_mul.P0
    ; сохранение адресов аргументов в регистрах
    rdl qf_mat44_mul.a
    setl #32, @1
    rdl qf_mat44_mul.b
    setl #33, @1
    rdl qf_mat44_mul.c
    setl #34, @1
    complete

.local qf_mat44_mul.P0
qf_mat44_mul.P0:
    rdl #SP
    jmp @1
    ; чтение матрицы b
    va01 := rdq #32
    va23 := rdq #32,8
    va45 := rdq #32,16
    va67 := rdq #32,24
    va89 := rdq #32,32
    vaAB := rdq #32,40
    vaCD := rdq #32,48
    vaEF := rdq #32,56
    ; вспомогательные значения, для упаковки матрицы a в строки
    va54 := pack @va45, @va45
    vaDC := pack @vaCD, @vaCD
    va76 := pack @va67, @va67
    vaFE := pack @vaEF, @vaEF
    ; упаковка строк матрицы a
    va04 := patch @va45, @va01
    va8C := patch @vaCD, @va89
    va15 := pack @va54, @va01
    va9D := pack @vaDC, @va89
    va26 := patch @va67, @va23
    vaAE := patch @vaEF, @vaAB
    va37 := pack @va76, @va23
    vaBF := pack @vaFE, @vaAB
    ; чтение матрицы b
    vb01 := rdq #33
    vb23 := rdq #33,8
    vb45 := rdq #33,16
    vb67 := rdq #33,24
    vb89 := rdq #33,32
    vbAB := rdq #33,40
    vbCD := rdq #33,48
    vbEF := rdq #33,56
    ; скалярные произведения строк матрицы a со стобцами матрицы b
    madd @va04, @vb01
    madd @va8C, @vb23
    vc_0 := addf @1, @2
    madd @va15, @vb01
    madd @va9D, @vb23
    vc_1 := addf @1, @2
    madd @va26, @vb01
    madd @vaAE, @vb23
    vc_2 := addf @1, @2
    madd @va37, @vb01
    madd @vaBF, @vb23
    vc_3 := addf @1, @2
    ; --
    madd @va04, @vb45
    madd @va8C, @vb67
    vc_4 := addf @1, @2
    madd @va15, @vb45
    madd @va9D, @vb67
    vc_5 := addf @1, @2
    madd @va26, @vb45
    madd @vaAE, @vb67
    vc_6 := addf @1, @2
    madd @va37, @vb45
    madd @vaBF, @vb67
    vc_7 := addf @1, @2
    ; --
    madd @va04, @vb89
    madd @va8C, @vbAB
    vc_8 := addf @1, @2
    madd @va15, @vb89
    madd @va9D, @vbAB
    vc_9 := addf @1, @2
    madd @va26, @vb89
    madd @vaAE, @vbAB
    vc_A := addf @1, @2
    madd @va37, @vb89
    madd @vaBF, @vbAB
    vc_B := addf @1, @2
    ; --
    madd @va04, @vbCD
    madd @va8C, @vbEF
    vc_C := addf @1, @2
    madd @va15, @vbCD
    madd @va9D, @vbEF
    vc_D := addf @1, @2
    madd @va26, @vbCD
    madd @vaAE, @vbEF
    vc_E := addf @1, @2
    madd @va37, @vbCD
    madd @vaBF, @vbEF
    vc_F := addf @1, @2
    ; упаковка результатов
    vc01 := patch @vc_1, @vc_0
    vc23 := patch @vc_3, @vc_2
    vc45 := patch @vc_5, @vc_4
    vc67 := patch @vc_7, @vc_6
    vc89 := patch @vc_9, @vc_8
    vcAB := patch @vc_B, @vc_A
    vcCD := patch @vc_D, @vc_C
    vcEF := patch @vc_F, @vc_E
    ; запись результатов
    wrq @vc01, #34
    wrq @vc23, #34,8
    wrq @vc45, #34,16
    wrq @vc67, #34,24
    wrq @vc89, #34,32
    wrq @vcAB, #34,40
    wrq @vcCD, #34,48
    wrq @vcEF, #34,56
    complete

Есть кой-какие вопросы о том, как сделать её максимально быстрой:

1.) Имеет ли смысл сохранять адреса аргументов в индексных регистрах для дальнейшего использования?

Т.е. сделав:

    rdl qf_mat44_mul.a
    setl #32, @1

Далее можно загрузить матрицу так:

    va01 := rdq #32
    va23 := rdq #32,8
    va45 := rdq #32,16
    va67 := rdq #32,24
    va89 := rdq #32,32
    vaAB := rdq #32,40
    vaCD := rdq #32,48
    vaEF := rdq #32,56

Вместо того, чтобы читать адрес в коммутатор и вычислять адреса вот так:

    pa01 := rdl qf_mat44_mul.a
    pa23 := addl @pa01, 8
    pa45 := addl @pa01, 16
    pa67 := addl @pa01, 24
    pa89 := addl @pa01, 32
    paAB := addl @pa01, 40
    paCD := addl @pa01, 48
    paEF := addl @pa01, 56
    va01 := rdq @pa01
    va23 := rdq @pa23
    va45 := rdq @pa45
    va67 := rdq @pa67
    va89 := rdq @pa89
    vaAB := rdq @paAB
    vaCD := rdq @paCD
    vaEF := rdq @paEF

Но последнее позволяет реализовать функцию одним параграфом. Т.е. меня интересует есть ли смысл избегать переключения параграфов, а также скорость выполнения чтения из адреса в регистре со смещением и из вычисленного адреса в коммутаторе. Возможно есть какие-то подводные камни.

2.) Имеет ли смысл минимизировать кол-во операций записи в память?

Например, тут у меня сделано так:

    ; упаковка результатов
    vc01 := patch @vc_1, @vc_0
    vc23 := patch @vc_3, @vc_2
    vc45 := patch @vc_5, @vc_4
    vc67 := patch @vc_7, @vc_6
    vc89 := patch @vc_9, @vc_8
    vcAB := patch @vc_B, @vc_A
    vcCD := patch @vc_D, @vc_C
    vcEF := patch @vc_F, @vc_E
    ; запись результатов
    wrq @vc01, #34
    wrq @vc23, #34,8
    wrq @vc45, #34,16
    wrq @vc67, #34,24
    wrq @vc89, #34,32
    wrq @vcAB, #34,40
    wrq @vcCD, #34,48
    wrq @vcEF, #34,56

Но можно сделать и так:

    wrl @vc_0, #34
    wrl @vc_1, #34,4
    wrl @vc_2, #34,8
    ...
    wrl @vc_E, #34,56
    wrl @vc_F, #34,60

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


Replies (82)

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by qewerty over 10 years ago

krufter_multiclet, оптимизированную, это какая имеется в виду?

Так-то всё здесь: https://bitbucket.org/qewerty/qf/overview. Там лучшая реализация, которая у меня получилась. Всё, что начинается c qf_mat44_mul*: в qf_mat44_mul.s сама функций, qf_mat44_mul_BENCH.s - цикл её использующий, qf_mat44_mul_TEST.c - сишная запускалка.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by krufter_multiclet over 10 years ago

Модель для windows обновлена, для Linux выложу чуть позже.
qewerty, спасибо за ссылку.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by sprin over 10 years ago

qewerty wrote:

Так-то всё здесь: https://bitbucket.org/qewerty/qf/overview. Там лучшая реализация, которая у меня получилась. ...

Здравствуйте, периодически заглядываю в ваш репозиторий :)

Появились некоторые замечания и предложения по файлу "qf_mat44_mul.s" :

  • Если во время выполнения первого параграфа "qf_mat44_mul:" произойдёт прерывание (на него ведь можно повесить внешнюю подпрограмму использующую стек?), то может перезаписываться стек с сохранёнными регистрами (#32, #33, #34), т.к. #SP в программе не меняется. Поэтому немного подправил код (см. ниже). Исходил из того, что значения регистров по команде "setl" меняются после "complete" (надеюсь понял правильно).
  • Ещё предлагаю разбить блок "Вспомогательные значения для упаковки матрицы a в строки" на 2 части. Т.к. считывание в @vaCD и @vaEF и их использование находятся слишком близко.
    Хотя, скорее всего это никак не повлияет на производительность, если ВСЕ предыдущие команды выполняются за 1 такт и распределение по клеткам МП происходит подряд циклически от начала параграфа, то если посчитать, то вроде пройдёт нормально. Но пока точно не установлено, что все команды за 1 такт, то лучше поставить чуть подальше :)
  • Тут возник ещё один вопрос. Может разнести между собой команды типа:
    rdl #SP
    jmp @1

    Теоретически у них есть зависимость и, следовательно, одна клетка вначале будет ждать результата другой.
  • + Немного поправил комментарии.

Можете протестировать?

Чтобы быстрее разобраться со стеком нарисовал картинку:

Show

Подправленный файл qf_mat44_mul.s:

Show

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by krufter_multiclet over 10 years ago

1)Если вы подключаете к проекту crt0.o, то стек после прерывания и выхода из обработчика не изменится по сравнению с состоянием стека до прерывания.
Если вы не подключаете к проекту crt0.o, то работу со стеком берёте на себя.

2)Это можно проверить, вы можете записаться на любое удобное для вас время(можно и на большее чем обычно время) для удалённого тестирования.

3)Да если параграф имеет много команд, то разнесение может немного улучшить результат.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

krufter_multiclet, Модель для windows обновлена, для Linux выложу чуть позже.

Очень хочется Linux'овую :) И где её потом искать? Под win самая свежая от 15.07.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Ещё очень не хватает в выводе mc-model видеть текущий адрес инструкции, особенно это полезно после условных переходов:

$ mc-model -d -inst-asm -inst-render -inst-strange -dump-raw -dump-addr -dump-byte -dump-symbol -dump-length 4 -dump-from 0x00000000 image.bin

PM1:
  i=31
  jmp 0x82;  ir = 7a08000000000082  opcode=1e   suf=2  type=0  F1=0  F2=0 V=82       arg1=3   arg2=82  *sb=82  flag.f=0
   0.0000000000000082 <= 0000000000000003, 0000000000000082 :  cop= 1E sfx= 2 top= 0 cmp= 1 tau= 0 F1=  0 F2=  0 : jmp    0x82
--- complete ---------------------

PM0:
  i=32
  rdq #20;   ir = 8532202000000000  opcode=21   suf=1  type=3  F1=0  F2=20 V=0       arg1=3   arg2=88  *sb=35f7c1b6e08d29a4  flag.f=0
   0.35f7c1b6e08d29a4 <= 0000000000000003, 0000000000000088 :  cop= 21 sfx= 1 top= 3 cmp= 0 tau= 22 F1=  0 F2= 20 : rdq    #20

PM1:

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Ещё mc-model был застукан:

$ strace -fF /usr/local/bin/mc-model -interactive image.bin
[…]]
close(3)                                = 0
open("//tmp//dbg_pipe_sout", O_RDONLY)  = -1 ENOENT (No such file or directory)
read(4294967295, 0x8178f60, 13)         = -1 EBADF (Bad file descriptor)
read(4294967295, 0x8178f60, 13)         = -1 EBADF (Bad file descriptor)
Забыта проверка на NULL.
У самого же mc-dbg где-то коркается потомок:
[pid  9088] clone(Process 9089 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6f9d46c9d0) = 9089
[pid  9088] exit_group(0)               = ?
Process 9088 detached
[pid  9087] <... sync resumed> )        = ? ERESTART_RESTARTBLOCK (To be restarted)
[pid  9087] --- SIGCHLD (Child exited) @ 0 (0) ---
[pid  9087] restart_syscall(<... resuming interrupted call ...> <unfinished ...>
[pid  9089] --- SIGSEGV (Segmentation fault) @ 0 (0) ---
Process 9089 detached
<... restart_syscall resumed> )         = 0
pipe2([5, 6], O_CLOEXEC)                = 0
Сам mc-dbg пытается открыть тот же /tmp//dbg_pipe_sout после "pidof mc-model", но уже с O_WRONLY. Кто его создавать должен?
PS. Сделал руками mkfifo /tmp/dbg_pipe_sout и /tmp/dbg_pipe_sin. Всё заработало.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by krufter_multiclet over 10 years ago

В текущей версии сначала запускается отладчик, который создаёт пайпы, а затем запускается модель которая считает, что всё для её работы уже готово. Так что пока сделана такая жёсткая привязка, в дальнейшем от неё уйдём.

Ещё очень не хватает в выводе mc-model видеть текущий адрес инструкции, особенно это полезно после условных переходов:

Данное пожелание учтено, как появится время, так оно и реализуется в модели.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

В текущей версии сначала запускается отладчик, который создаёт пайпы

В том-то и дело, что он их не создаёт, а пытается открыть только на запись и только один из двух и только после попытки запустить mc-model.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by krufter_multiclet over 10 years ago

Т.е. никакую программу не получалось отработать с помощью отладчика? Или это только на конкретной программе?

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Если удалить файлы /tmp/dbg_pipe_s{out,in} и запустить:

$ mc-dbg --mode model image.bin

Multiclet Corp. Debugger v 0.5.0
MC-MODEL was started ...
Connection with mc-model BAD...

Падает и не работает. Если же создать вручную пайпы перед запуском:

$ mkfifo /tmp/dbg_pipe_s{in,out}
$ mc-dbg --mode model image.bin

Multiclet Corp. Debugger v 0.5.0
MC-MODEL was started ...
Connection with mc-model GOOD...
…то всё отлично.

Под strace'ом видно как сначала стартует модель и падает в корку (иногда видно, что после безуспешной попытки открыть пайп), а затем mc-dbg также безуспешно пытается открыть второй пайп только на запись:

open("//tmp//dbg_pipe_sout", O_WRONLY) = -1 ENOENT (No such file or directory)

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

В модели encode/decode прекрасно работают (даже друг за другом). А на реальной железке подвисает на gost_decode. В аттаче два скомпиленных образа:
  • image-enc.bin выполняет gost_encode и вешается на gost_decode
  • image-dec.bin сразу вешается на gost_decode

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by krufter_multiclet over 10 years ago

А в этом параграфе всё нормально?

gost.save_results:
    rdl #SP, 12
newp :=    addl @1, 4
    getl #BB
    getl #AA
    wrl @2, @4    /* Сохраняем новые значения в буфере */
    wrl @2, @4
    wrl @newp, #SP, 12 /* Сохраняем новый указатель в стеке */
    jmp gost.next_block
complete

Тут вы два раза пишете по одному адресу в середине и в конце. В принципе при первом просмотре не заметил где стек портится.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Я уже это место переписал с использованием локальной переменной. Проблема, видимо, где-то ещё %) Я же могу из функции изменить содержимое по указателю, переданному через стэк, в частности, изменить содержимое массива? Странности в этом куске есть. Если закомментировать:

wrl @newp, BufPtr

То из функции уже получается вернутся и не раз, только значения, вычитываемые из адреса начального буфера (_buf @ 0xc8) совсем не те. В симуляторе, вроде, всё ок. Параметры дальше тоже передавались нормальные, насколько я смог разобрать.

На реальном железе в терминале вижу вместо:

System is booting...
629D1FC2, B61F9AA0enc={629D1FC2, B61F9AA0}
dec={629D1FC2, B61F9AA0}
Вывод:
System is booting...
629D1FC2, B61F9AA0enc={629D1FC2, B61F9AA0}
dec={629D1FC2, B61F9AA0}
enc={, }
dec={, }
И в цикл с миганием VD3-VD4 не входит. Должно быть 13 вызовов uart_send_str,а по факту их больше. Где-то какой-то косяк в программе и это даже с полностью отключеной записью результатов в память.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by krufter_multiclet over 10 years ago

Завтра проанализирую ещё раз код посмотрим где ошибка и кто портит стек. Содержимое массива вы менять можете, вычитав из стеке адрес массива.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Добавил а-ля шелл. Команды:

print — вывод текущего значения буфера
encode — шифрование
decode — расшифровывание
enc-print — шифрование и вывод результата
dec-print — расшифровывание и вывод результата
Вот если закомментировать wrl @newp, BufPtr, то из decode возвращаемся, но сразу печатается какой-то мусор. Команда "encode" завершается всегда успешно, но после второго вызова возвращает неверные значения. Тестовая программка на Си в файле t.c:
aa=b61f9aa0 bb=629d1fc2
aa=ed7e2975 bb=d48f796f
aa=7afe35fe bb=1de5ecf9
aa=ef90cb87 bb=c47ddb72
Мой код вживую выдаёт (разная последовательность AA/BB — это ок):
{629D1FC2, 9A1F9AA0}
{ECECFDF5, 9AA06670}
{34856A37, 9A74F7C0}
В модели всё нормально ­— тестовые результаты совпадают с моделью.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by sprin over 10 years ago

mouse, вы свою программу по ГОСТ доделали?
Я тут посмотрел вашу реализацию из "test-gost-7.tar.gz", в ASM реализации неверно сделаны циклы по параграфам и ещё несколько неточностей.
А у вас main.c нормально компилируется? Вроде текущий компилятор не поддерживает формат 64 бита и Sblock интерпретируется неверно (+ адресация к массиву). Вы уверены, что у вас считает в модели нормально?

Попозже выложу поправленный тестовый код на С и ASM.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Модель работает как часы. На реальном железе есть проблемы.
В чём некорреткность циклов и какие неточности?

Вроде текущий компилятор не поддерживает формат 64 бита и Sblock интерпретируется неверно

Причём здесь Sblock (local), который определён в ассемблерном коде и компилятор Си?

Вы уверены, что у вас считает в модели нормально?

Конечно, проверял пошагово.
PS. прикладываю посвежее версию.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by sprin over 10 years ago

Ой, да я неверно написал имя файла, я имел ввиду файл "t.c", в нём есть sblock. За основу взял этот файл и анализировал как реализовано у вас для ASM. Поправил ваш файл и немного сделал в другом формате, а то немного неудобно было ставить метки. Назвал "gost_2.asm"

К сожалению ваша ASM реализация у меня на модели ("MultiCletSDK_ru.20130814.exe") уходит в цикл, а на новом "MultiCletSDK_ru.20130906.exe" выходит с ошибкой по обращении к памяти.

По ASM реализации:
  • gost.load_key1_24 - всегда прыгает на gost.round
  • gost.load_key25_32 - всегда прыгает на gost.round
  • gost_enc.epilogue - несколько условий перехода, которые могут одновременно быть истинными (? уточнить) (в модели возможно переход будет по последнему обработанному, а на железе неизвестно)
  • gost_dec.epilogue - несколько условий перехода, которые могут одновременно быть истинными (? уточнить) (в модели возможно переход будет по последнему обработанному, а на железе неизвестно)
  • gost.save_results - новый указатель должен быть ещё на 4 больше
  • нет сохранения используемых регистров

По поводу gost_enc.epilogue и gost_dec.epilogue тут надо уточнить:

код из "t.c" enc_epilogue и dec_epilogue

Show

если они одновременно выполняться не могут, то потом можно поправить реализацию этого места. А пока сделал как в коде (т.е. считал, что оба условия могут выполниться при вызове функции).


По поводу "t.c":
  • компилятор некорректно обрабатывает массив sblock, если посмотреть в ASM файле, то там часть данных = "0xFFFFFFFF" (проверял на "MultiCletSDK_ru.20130814.exe")
  • в void gost_round(): "fAiKi |= ((sblock[i] >> (((axk >> (i*4)) & 0xf) << 2)) & 0xf) << (i*4);" должно быть обращение к данным sblock[i] как 64 бита? Если да, то тут тоже немного неверно (опять компилятор). Поэтому дописал отдельную функцию slr64.

Возможно я что-то напутал или неправильно понял в реализации, так что прошу сильно не быть :)

Если нормально заработает, то можно будет подумать как дополнительно оптимизировать.


RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Файл t.c не используется в сборке — это эталон на Си под gcc. (в коде встречается множественный printf и наколенный ROL вместо одной ассемблерной инструкции).

gost.load_key1_24 - всегда прыгает на gost.round
gost.load_key25_32 - всегда прыгает на gost.round

В конце параграфа мы обязаны куда-то перейти. Перед вызовом gost.round нам надо подгрузить следующий ключ Ki из последовательности 32-х ключей. Не очень понял в чём особенность.

gost_enc.epilogue - несколько условий перехода, которые могут одновременно быть истинными (? уточнить) (в модели возможно переход будет по последнему обработанному, а на железе неизвестно)
gost_dec.epilogue - несколько условий перехода, которые могут одновременно быть истинными (? уточнить) (в модели возможно переход будет по последнему обработанному, а на железе неизвестно)

Данные условия мы пилили совместно с krufter_multiclet. Это единственный дешёвый способ перейти по нескольким условиям, не прибегая к ещё одному параграфу и повторной перепроверке условий. Условия построены таким образом, чтобы осуществить единственное возможное ветвление.

gost.save_results - новый указатель должен быть ещё на 4 больше

Согласен, надо было сделать ещё один addl @1, 4 перед модификацией BufPtr.

нет сохранения используемых регистров

Это в туду. Работе не мешает — ещё ни разу не видел, чтобы компилятор использовал задействованные мною регистры.

Посмотрел на код. Вся эта магия с or/and/xor ровно для того, чтобы можно было проверить несколько условий в пределах одного параграфа. Ещё три параграфа с кучей кода явно излишне.
Про переходы по #N_P не очень понимаю:
В параграфе gost_dec.epilogue.2 #N_P принимает значение gost_dec.epilogue.3. При выполнении одного из условий мы перейдём в load_keys1_24, подгрузим ключи, а потом перейдём в gost_dec.epilogue.3, где опять повыполняем немного условий и перейдём-таки в gost.round уже без оглядки на #N_P. Как мне кажется, схема ветлвений перестала быть прозрачной, появился оверхед по инструкциям.

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

Новая модель из SDK 06/Сен падает ещё в crt0:

$ mc-model -inst-asm -inst-strange -dump-raw -dump-addr -dump-byte -dump-symbol -dump-length 4 -dump-from 0x00000000 image.bin
1.0000000000000000 <= 00000000ff9d5c6a, 0000000000000000 :  getl   0x0
0.0000000000000000 <= 0000000000000039, 0000000000000000 :  setl   #MODR(57), @1
0.0000000000000008 <= 0000000000000039, 0000000000000008 :  jmp    0x8
0.0000000000020000 <= 0000000000000039, 0000000000020000 :  getl   0x20000
1.0000000000000000 <= 0000000000000039, 0000000000000000 :  getl   0x0
0.0000000000000004 <= 0000000000000039, 0000000000000004 :  getl   0x4
0.000000000001fffc <= 0000000000020000, 0000000000000004 :  subl   @3, 0x4
0.000000000001fff8 <= 000000000001fffc, 0000000000000004 :  subl   @1, 0x4
Segmentation fault (core dumped)
При этом, из-под gdb и valgrind работает.
В корке (прилагается):
#0  0x08051c75 in EXECUTION(unsigned long long, unsigned long long*,
          int, int*, unsigned long long*, unsigned long long*, int*, unsigned long long*,
          unsigned long long*, unsigned int*, unsigned int*, int*, int, unsigned long long*) ()
#1  0x08049088 in main ()

RE: Программирование на ассемблере. Пара вопросов о производительности - Added by mouse over 10 years ago

ГОСТ в модели выдаёт:

8.00000000b61f9aa0 <= 0000000000000000, 00000000b61f9aa0 :  getl   #1
0.00000000629d1fc2 <= 0000000000000000, 00000000629d1fc2 :  getl   #2

8.00000000ed7e2975 <= 0000000000000000, 00000000ed7e2975 :  getl   #1
8.00000000d48f796f <= 0000000000000000, 00000000d48f796f :  getl   #2

0.000000007afe35fe <= 0000000000000000, 000000007afe35fe :  getl   #1
0.000000001de5ecf9 <= 0000000000000000, 000000001de5ecf9 :  getl   #2
Вывод эталона на Си:
aa=b61f9aa0 bb=629d1fc2
aa=ed7e2975 bb=d48f796f
aa=7afe35fe bb=1de5ecf9

Т.е. результаты для трёх прогонов на одном буфере совпадают. Для decode ситуация ровно такая же. Всё работает как часы.

На реальном железе, собранное всё последним SDK так же не работает — encode во второй круг выдаёт: { ECECFDF5, 9AA06670 }, а decode просто вешает.

(51-75/82)