gost-engine / engine

A reference implementation of the Russian GOST crypto algorithms for OpenSSL
Apache License 2.0
378 stars 174 forks source link

Build under Windows 10 Pro x64 #198

Open jonasbassl opened 4 years ago

jonasbassl commented 4 years ago

Hello,

I'm very sorry, but I really struggle to build the gost engine for Windows 10 Pro x64. Can anyone give me advice on the compiling or tell me how the best way is to do it?

I compiled m own OpenSSL from the master branch linke described here: https://gist.github.com/terrillmoore/995421ea6171a9aa50552f6aa4be0998

I tried both, the master branch and the openssl_1_1_0 branches.

I tried several ways to install the gost engines:

I installed cygwin, I installed Mingw...

Has anyone of you already done this in Win10 Pro x64 and can give me a short description, what there is to do to make it happen?

Which branch should I use? Should I use Visual Studio for it?

beldmit commented 4 years ago

Unfortunately, I didn't try to build and test the engine for windows. I recommend using mingw for openssl and for the engine. It's better to use 1_1_0 branch, I think.

ddulesov commented 4 years ago

Original gost-engine has lack of Windows build system and doesn't support MSVC runtime. I recommend use fork https://github.com/ddulesov/engine.git for this purpose.

How-to build and configure OpenSSL gost engine under Windows x64 + MSVC

  1. install binary redistributable Windows OpenSSL(Win64 v1.1.1d (c) ) https://slproweb.com/products/Win32OpenSSL.html

  2. Install

    • Visual Studio 2017 (I have successfully used Visual Studio 2015 )
    • cmake for Windows
  3. Build GOST Engine with MSVC runtime library

    git clone --depth 1 https://github.com/ddulesov/engine.git
    cd engine   
    cmake -DCMAKE_GENERATOR_PLATFORM=x64 -DOPENSSL_CRYPTO_LIBRARY=libcrypto64MT.lib  -DOPENSSL_ENGINES_DIR="C:\Program Files\OpenSSL-Win64\bin"  -B ./win_amd64 .

    build gost-engine.sln solution using Visual Studio IDE or just run in vcvars command line:

    cd win_amd64
    msbuild gost-engine.sln /p:Configuration=Release /p:Platform=x64
  4. put the resulted "bin\Release\gost.dll" in the engines dir (i.e under OpenSSL installation directory)

    make changes to openssl config file adding next lines:

    openssl_conf = openssl_def
    [openssl_def]
    engines = engine_section
    
    [engine_section]
    gost = gost_section
    
    [gost_section]
    engine_id = gost
    dynamic_path = <provide path to gost.dll>
    default_algorithms = ALL
    CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet

    To ensure that everything is correct run tests under bin\Release directory

beldmit commented 4 years ago

@ddulesov do you plan to make some contributions? MSVC build is welcome and some other your improvements seem reasonable too.

ddulesov commented 4 years ago

@ddulesov do you plan to make some contributions? MSVC build is welcome and some other your improvements seem reasonable too.

Recently I filed several pull requests. None of them has been considered yet.

beldmit commented 4 years ago

Well, the MSVC one will be :)

vt-alt commented 4 years ago

Recently I filed several pull requests. None of them has been considered yet.

Btw, there are no outstanding pull requests from you: https://github.com/gost-engine/engine/pulls

chipitsine commented 4 years ago

https://github.com/gost-engine/engine/pulls?q=is%3Apr+author%3Addulesov+is%3Aclosed

vt-alt commented 4 years ago

@chipitsine?

chipitsine commented 4 years ago

There are no outstanding PRs, but there are some closed.

I'd suggest to open new PR on win10 build, it is useful

ddulesov commented 4 years ago

The previous https://github.com/gost-engine/engine/pulls?q=is%3Apr+author%3Addulesov+is%3Aclosed has been canceled by me because you asked me split it into small chunks. I was mistaken talking about others pull requests. I've not sent all prepared PR, only first one. Now sending them makes no sense; that changes are outdated. Unfortunately I have no time for splitting my changes into chunks again because too many changes was made;

Now travis CI is on and all tests are passed. You can merge changes by yourself.

P.S. I insist on using OpenSSL-stable ver 1.1 branch for tests and travis CI. The master branch of gost-engine is based on OpenSSL 1.1. But OpenSSL master is 3.x and it is under active development withal. These incompatibilities make tests fail.

vt-alt commented 4 years ago

JFYI. This is not how FOSS development works.

chipitsine commented 4 years ago

насчет тестов, ветка master была выбрана специально. в ваших словах есть здравый смысл, пожалуй, стоит тестировать на 2 ветки - master и 1.1.1

это несложная штука, я сделаю, но не обещаю, что быстро.

насчет остального, в мире opensource встречаются разные по степени дружественности подходы. от таких, про которые говорит Виталий (и в некоторых случаях еще надо долго бегать за апрувом и выслушивать от мейнтейнеров, что им некогда) до тех, про которые вы говорите (типа "ну я все сделал, дальше вы сами").

vt-alt commented 4 years ago

"ну я все сделал, дальше вы сами"

В каких FOSS проектах такой подход, если не секрет?

chipitsine commented 4 years ago

openresty

vt-alt commented 4 years ago

openresty

Спасибо. (Я глянул в openresty/openresty - на вид обычный приём PR.)

Мелкие изменения и merge conflicts могут фиксить коммиттеры и в ядре Линукс.

Безответсвенные люди могут прикладывать чужие патчи без атрибуции (например в openvz). А код может быть с тысячами багов, без тестов и быть чем попало написанным левой ногой, в FOSS проектах. Но это не то к чему надо стремиться в gost-engine.

vt-alt commented 4 years ago
  1. LDV предложил такие монстроидальные изменения даже не смотреть.
  2. Чтоб ваш труд не пропадал понапрасну, а качество gost-engine не падало, а росло, я бы на вашем месте сделал так:
    • Не надо слать большое количество разных изменений в одном огромном pull request (PR). Надо понимать, что любому коду требуется review.
    • Сделайте несколько PR различающихся по смыслу (а можно и по затрагиваемому коду). Скажем "сборка под windows", "enable SSE2", "оптимизация streebog", "benchmark", "pretty printing", "tests" и т.д. Не обязательно их ставить все одновременно, особенно, если одно будет зависеть от другого.
    • Вариант как это сделать - завести несколько бранчей, перенести туда нужные изменения, оформить коммиты (научиться git-у), сделать rebase поверх master, сделать PRы.
    • Не спеша разобраться с каждым PR по порядку. (Например, я буду против оптимизации кода Стрибога, если она будет не понятна и не будет давать прироста производительности как ваша предыдущая оптимизация.) Это совершенно обычный цикл разработки для нормальных проектов.
ddulesov commented 4 years ago
  1. LDV предложил такие монстроидальные изменения даже не смотреть.

@vt-alt я не предлагаю все эти изменения применить как одно. рассмотрите их, оцените целесообразность каждого прежде чем я или другой контрибьютор начнет подготовку PR. Эта ветка обсуждения возникла как ответ на вопросы тех, кто, как и я в недавнем прошлом, столкнулся со сложностью сборки под Windows MSVC. Я даже не планировал создавать PR для этого. Сейчас для меня этот вопрос решен и если есть потребность в этом, мог бы внести свой посильный вклад.

  1. Чтоб ваш труд не пропадал понапрасну, а качество gost-engine не падало, а росло, я бы на вашем месте сделал так:
  • Не надо слать большое количество разных изменений в одном огромном pull request (PR). Надо понимать, что любому коду требуется review.

Я это прекрасно понимаю. Поэтому сделал попытку выделить небольшую часть из всего того пула изменений и выслать на рассмотрение только одно #190 В результате . Небольшим изменением я не "убедил", что оно значимо. Большее по объему - уже Не воспринимается вами. В том PR я подмешал одно дополнительное изменение - смена ветки openssl в .travis.yml. Это было вынужденное решение, так как в моем понимании PR не должен нарушать работу и travis passed notification должен был свидетельствовать об этом. Позднее я выделил это изменение в отдельный PR , который также был отклонен. В результате в проекте не работает полноценный CI , который мог бы способствовать эффективной работе PR review и применению изменений.

  • Сделайте несколько PR различающихся по смыслу (а можно и по затрагиваемому коду). Скажем "сборка под windows", "enable SSE2", "оптимизация streebog", "benchmark", "pretty printing", "tests" и т.д. Не обязательно их ставить все одновременно, особенно, если одно будет зависеть от другого.

Боюсь, что у меня не будет на это времени.

  • Вариант как это сделать - завести несколько бранчей, перенести туда нужные изменения, оформить коммиты (научиться git-у), сделать rebase поверх master, сделать PRы.
  • Не спеша разобраться с каждым PR по порядку. (Например, я буду против оптимизации кода Стрибога, если она будет не понятна и не будет давать прироста производительности как ваша предыдущая оптимизация.)

@vt-alt Во-первых, тот PR #190 был первым в серии изменений функции streebog и затрагивал исключительно только один аспект - устранение излишнего использования промежуточных буферов памяти при обработке входных данных функции streebog. Сложно было от этого заметить сколько-нибудь существенного изменения в синтетическом тесте, проводимом в обычных (не под высокой нагрузкой на шину данных и процессорный кеш ). В большей степени на результаты могло повлиять то, как компилятор обработал эти изменения и создал результирующй код. Если при этом сравнительное тестирование показало значимое падение скорости, нужно дополнительное внимание к параметрам компиляции и используемому компилятору. Во всяком случае мне не удалось выявить такого падения. Разброс показаний скорости выполнения алгоритма до и после , в бОльшей степени вызван случайными факторами . Вот данные полученные в серии прогонов , сравниваются черным - базовая реализация, синим - с применением патча. https://user-images.githubusercontent.com/27359066/71379638-147da480-25dd-11ea-8022-8f376b85002d.png.

С какой целью были внесены эти изменения. Изменение нужно было для следующего шага - использование возможностей CPU архитектуры x86 эффективно читать 128бит невыровненные данные + задействование SSE2 оптимизированных инструкций для выполнения LPS преобразования алгоритма streebog. Это раскрывает потенциал современных CPU построенных на этой архитектуре и дает заметный прирост в скорости. Для SIMD оптимизаций я использовал практически без изменения уже имеющийся в кодовой базе, но по какой-то причине выключенный из сборки, gosthash2012_sse2.h - реализацию Дегтярева. Изменения в PR сделаны с учетом того ,чтобы избежать негативного влияния на производительность для прочих архитектур, не реализующих SSE и неспособных читать невыровненные данные. Но этот момент требует отдельной проверки. Я не имею возможности провести качественный тест на широком круге архитектур. (отмечу, что travis CI проходит все тесты для x86_64/ppc/aarch64 для linux/osx собранные gcc/clang , но опираться на скоростные покатели при выполнении в среде travis нельзя)

Привожу тесты для x86_64, полученные по итогам применения тех изменений, которые касаются streebog.

Intel Core i5-4210U CPU @ 1.70GHz Linux x86_64 GNU/Linux

compare streebog digest calculation

github.com/gost-engine/engine @09615031fffa93d7b42af7ad1029d963445c7c74

GOST-R 34.11-2012(512). block size / digest speed, MBps
 /size          32        64       256      1024      8192      9732     65536
------------------------------------------------------------------------------
       1      6.83     11.18     26.80     40.96     46.02     43.10     41.69
       2      5.45     11.47     27.70     41.38     48.18     48.54     47.43
       3      7.19     11.55     27.50     41.05     48.20     48.45     47.10
       4      7.48     11.51     28.26     41.35     47.46     49.62     48.27
       5      7.52     11.69     27.70     42.30     48.75     49.36     50.12
------------------------------------------------------------------------------

github.com/ddulesov/engine @e8b84331c31fb38f2eed437f4675633b846e0f3e

 GOST-R 34.11-2012(512). block size / digest speed, MBps
 /size          32        64       256      1024      8192      9732     65536
------------------------------------------------------------------------------
       1     13.58     22.38     55.46     87.51    100.05    103.75     98.60
       2     12.70     20.12     53.74     86.84    102.69    103.32    105.44
       3     13.70     21.90     55.48     87.48    102.09     91.67    104.02
       4     13.64     21.16     49.96     86.11    101.11    103.12     99.33
       5     13.38     21.64     54.34     84.41    102.17     90.81     99.52
------------------------------------------------------------------------------

в обоих случаях сборка производилась так

#cmake -DOPENSSL_ROOT_DIR=${PREFIX} -DOPENSSL_LIBRARIES=${PREFIX}/lib -DOPENSSL_ENGINES_DIR=${PREFIX}/lib/engines-1.1 .. && make

gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

на базе OpenSSL 1.1.1e github.com/openssl/openssl/tree/OpenSSL_1_1_1-stable @c8943eb04ae41506ec8a1869103e2e1dec6bfcd8

platform: linux-x86_64 options: bn(64,64) rc4(16x,int) des(int) idea(int) blowfish(ptr) compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG

Это показывает, что для архитектуры x86_64 задействование SIMD дает практически **100% увеличение скорости работы*** функции streebog-hash.

И второе. Все это синтетические тесты, которые весьма далеки от реального использования алгоритма. Тестовые данные кратны 64 байт, то есть размеру блока данных алгоритма streebog. В этом случае при выполнении исключается ветка алгоритма, выполняющая паддинг данных. В реальных условиях данные могут быть любой длины. Давайте сравним результаты прикладного теста. В наборе утилит есть gost12sum, которая выполняет вычисление и сравнение хеш-сумм файлов. В форкнутой версии я добавил утилиту gost1sum с той же функциональностью. При выполении проверки хеш-сумм этими утилитами основное время затрачивается алгоритмом вычисления хеша. Для тестирования можно использовать любой набор файлов общим объемом от 1Гб. В этом случае уменьшается влияние случайных факторов. Для уменьшения влияния кеширования данных в ядре Linux тесты лучше повторить несколько раз.

Создаем check-file

#find /path_to_files(>1Gb)  -type f -exec ./bin/gost12sum -v {} \; > .check

сравниваем время проверки хеш сумм

из upstream github.com/gost-engine/engine

#time ./bin/gost12sum -c .check

из github.com/ddulesov/engine

#time ./bin/gost1sum -c .check

Я не привожу свои данные . Предлагаю всем участникам обсуждения выполнить это сравнительное тестирование на доступных платформах. Мне было бы интересно взглянуть на результаты выполнения на Эльбрус и многопроцессорных aarch64 .

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

beldmit commented 4 years ago

@ddulesov, меня очень интересует патч, направленный на ускорение хеша. Но меня он интересует в полном объёме. Отдельная оптимизация некритичного в плане производительности куска в отрыве от всего контекста смысла особо лишена.

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

Про смену ветки openssl с master на 1.1.1 ситуация совсем отдельная. В данном случае engine ловит регрессию в openssl, и это сознательная политика - мне важно отследить изменения в openssl, которые ломают текущее поведение, и купировать их на ранней стадии. Я с удовольствием приму патч, который добавит тестирование с 1.1.1 в матрицу.

chipitsine commented 4 years ago

@ddulesov , насчёт трависа политика либеральная, на уровне репозитория можно установить обязательность проверок, тогда просто не получится принять пул реквест. Этого не сделано , даже при красных билдах вмержить получится

Ветку 1.1.1 я добавлю, там надо будет аккуратно разнести, что в cron, что нет. В след выходные сделаю

Может github actions настрою для 1.1.1

vt-alt commented 4 years ago

Это показывает, что для архитектуры x86_64 задействование SIMD дает практически 100% увеличение скорости работы* функции streebog-hash.

200% ускорение это замечательно! Но review всё равно необходим, чтоб не внести случайно ошибки в код. (А в Стрибоге уже целая история ошибок.) Желательно это делать отдельным PR, где мы сможем это обсудить. PR это инструмент для review. (В случае нормального PR я смогу потестировать на Эльбрусе, arm64, sparс64, ppc64le, mipsel).

Unfortunately I have no time for Боюсь, что у меня не будет на это времени.

Этого я не понимаю. Предполагается, что вы мотивированы и вам это интересно самому. Вы делаете работу, а потом бросаете на пол пути. Вам нужен интерн, который все причешет как надо. Или мы должны это делать? (У нас ведь полно времени.)

Впрочем, @beldmit решать, я лишь "адвокат" нормального подхода и поясняю в чем он состоит (очевидные вещи). Я считаю, что надо переходить с кустарных стандартов работы на профессиональные. Мне кажется gost-engine достаточно важным проектом достойным такого отношения.

Я не привожу свои данные .

?

beldmit commented 4 years ago

Update: Тут сравнение ошибочное @ddulesov, Ваш вариант даёт по openssl speed

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
GOST R 34.11-2012 with 256 bit hash     5068.77k    15678.27k    37301.33k    56989.35k    67431.08k    68414.12k

Мой вариант:

type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
GOST R 34.11-2012 with 256 bit hash     4992.35k    15434.45k    36784.21k    56153.43k    66469.89k    67321.86k

Собирал и там, и там с -msse4 компилятором gcc 8.3.0

beldmit commented 4 years ago

Но похоже, Вы правы и опции по умолчанию не детектят доступные Intel-овые наборы инструкций.

beldmit commented 4 years ago

@ddulesov прошу прощения, после копирования Ваших опций компиляции и Вашего кода по ГОСТ

type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
GOST R 34.11-2012 with 256 bit hash     9041.09k    28619.52k    70448.04k   111522.82k   133292.03k   135124.31k
ddulesov commented 4 years ago

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

@beldmit Ок. Давайте завтра я подготовлю PR , включающий только те изменения, которые необходимы, чтобы сделать код основных модулей и тестов кросплатформенными (имеется в виду поддержка Microsoft Windows runtime ). Хотя они простые и не изменяют основной функционал, тем не менее затрагивают большое число файлов.

ddulesov commented 4 years ago

200% ускорение это замечательно! Но review всё равно необходим, чтоб не внести случайно ошибки в код. (А в Стрибоге уже целая история ошибок.) Желательно это делать отдельным PR, где мы сможем это обсудить. PR это инструмент для review. (В случае нормального PR я смогу потестировать на Эльбрусе, arm64, sparс64, ppc64le, mipsel).

@vt-alt отлично. Я начну с PR включающего поддержку MSVC. После одобрения и принятия в основную ветку подготовлю PR c изменениями касающимися streebog.

beldmit commented 4 years ago

Собрал свой код с -march=native -DOPENSSL_IA32_SSE2

type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
GOST R 34.11-2012 with 256 bit hash     8790.15k    27944.87k    68004.18k   105399.30k   126500.86k   128150.19k

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

beldmit commented 4 years ago

https://github.com/adegtyarev/streebog

beldmit commented 4 years ago

@adegtyarev, Лёша, можно тебя попросить или засабмитить твои наработки по sse4 патчем сюда, или разрешить позаимствовать?

vt-alt commented 4 years ago

Надо ещё посмотреть на оптимизации Дегтярёва под SSE4.

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

@adegtyrev,

Опечатка.

vt-alt commented 4 years ago

Опечатка.

Не уверен, что после редактирвоания коммента письмо придёт.

vt-alt commented 4 years ago

Не уверен, что после редактирвоания коммента письмо придёт.

О, мне пришло. Значит всё ок!

beldmit commented 4 years ago

Не уверен, что после редактирвоания коммента письмо придёт.

Я тоже, поэтому старый комментарий я снёс, а новый добавил.

ddulesov commented 4 years ago

Собирал и там, и там с -msse4 компилятором gcc 8.3.0

Не ясно из контекста, как производилась сборка и какие именно ветки сравнивались. Судя по тому ,что цифры практически одинаковые это не SIMD версия. простое включение флага -msse2 только указывает компилятору на возможность использования соответствующих инструкций. При этом он может производить автовекторизацию кода . Код тяжелых функций (LPSX) алгоритма streebog по структуре такой, что не может быть эффективно векторизован компилятором. Поэтому Дегтярев (автор включенной в состав gost-engine реализации ) добавил в нее отдельную реализацию функции на интринсиках .

beldmit commented 4 years ago

Да, я уже осознал и сделал сборку с принудительным выставлением использования интринсиков. https://github.com/gost-engine/engine/issues/198#issuecomment-578931084 мой тайминг https://github.com/gost-engine/engine/issues/198#issuecomment-578928259 Ваш тайминг

ddulesov commented 4 years ago

я потерял нить рассуждений. абсолютные цифры значений сложно оценивать. они разнятся от процессора к процессору. (у меня CPU много слабее).
Что имеется в виду под "ваша реализация" Код непосредственно в github.com/ddulesov/engine ?

beldmit commented 4 years ago

Что имеется в виду под "ваша реализация" Код непосредственно в github.com/ddulesov/engine ?

Да.

Абсолютные цифры сравнивать бессмысленно. Осмысленно сравнивать производительность различных вариантов сборки. Я в качестве эталонной сравнивалки беру openssl speed.

vt-alt commented 4 years ago

198 (comment) мой тайминг #198 (comment) Ваш тайминг

Обе сборки под под SSE2? Значит ускорение на 6%. (К слову, у меня на AMD EPYC 7301 (1151.689 MHz) максимум, что я смог выдавить, это 101214.89k с gost3411-2012-sse2.h взятым из adegtyarev/streebog и записанным поверх того, что лежит в gost-engine, там есть небольшая разница. Для сравнения -ref давала 88599.21k.)

ddulesov commented 4 years ago

Собрал свой код с -march=native -DOPENSSL_IA32_SSE2

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

beldmit commented 4 years ago

Да, Ваш вариант на 6% быстрее

ddulesov commented 4 years ago

Если не затруднит, проведите сравнительное тестирование gost12sum и gost1sum в режиме проверки хэш-сумм по массиву файлов объемом от 1Гб. любопытно посмотреть на эти цифры

vt-alt commented 4 years ago

Если не затруднит, проведите сравнительное тестирование gost12sum и gost1sum в режиме проверки хэш-сумм по массиву файлов объемом от 1Гб. любопытно посмотреть на эти цифры

Чтоб убедиться, что параллельный подсчет быстрее однопоточного и поразиться этому?

vt-alt commented 4 years ago

Чтоб убедиться, что параллельный подсчет быстрее однопоточного

Я не спорю, что это полезная утилита, но use case у неё 0.01%.

Был бы смысл сравнивать 2 параллельные реализации и чтоб ваша выиграла. Сравнивать однопоточный подсчет и параллельный, это сравнение количества ядер на тестовой машине с 1.

vt-alt commented 4 years ago

объемом от 1Гб.

gost12sum в цикле читает файл в буфер объемом 262144, (что сравнимо с размером L2 кэша), при любом объеме файлов. Так к слову о ваших методиках тестирования.

chipitsine commented 4 years ago

пн, 27 янв. 2020 г. в 16:22, Dmitry Dulesov notifications@github.com:

  1. LDV предложил такие монстроидальные изменения даже не смотреть.

@vt-alt https://github.com/vt-alt я не предлагаю все эти изменения применить как одно. рассмотрите их, оцените целесообразность каждого прежде чем я или другой контрибьютор начнет подготовку PR. Эта ветка обсуждения возникла как ответ на вопросы тех, кто, как и я в недавнем прошлом, столкнулся со сложностью сборки под Windows MSVC. Я даже не планировал создавать PR для этого. Сейчас для меня этот вопрос решен и если есть потребность в этом, мог бы внести свой посильный вклад.

  1. Чтоб ваш труд не пропадал понапрасну, а качество gost-engine не падало, а росло, я бы на вашем месте сделал так:

    • Не надо слать большое количество разных изменений в одном огромном pull request (PR). Надо понимать, что любому коду требуется review.

Я это прекрасно понимаю. Поэтому сделал попытку выделить небольшую часть из всего того пула изменений и выслать на рассмотрение только одно #190 https://github.com/gost-engine/engine/pull/190 В результате . Небольшим изменением я не "убедил", что оно значимо. Большее по объему - уже Не воспринимается вами. В том PR я подмешал одно дополнительное изменение - смена ветки openssl в .travis.yml. Это было вынужденное решение, так как в моем понимании PR не должен нарушать работу и travis passed notification должен был свидетельствовать об этом. Позднее я выделил это изменение в отдельный PR , который также был отклонен. В результате в проекте не работает полноценный CI , который мог бы способствовать эффективной работе PR review и применению изменений.

  • Сделайте несколько PR различающихся по смыслу (а можно и по затрагиваемому коду). Скажем "сборка под windows", "enable SSE2", "оптимизация streebog", "benchmark", "pretty printing", "tests" и т.д. Не обязательно их ставить все одновременно, особенно, если одно будет зависеть от другого.

Боюсь, что у меня не будет на это времени.

  • Вариант как это сделать - завести несколько бранчей, перенести туда нужные изменения, оформить коммиты (научиться git-у), сделать rebase поверх master, сделать PRы.
  • Не спеша разобраться с каждым PR по порядку. (Например, я буду против оптимизации кода Стрибога, если она будет не понятна и не будет давать прироста производительности как ваша предыдущая оптимизация.)

@vt-alt https://github.com/vt-alt Во-первых, тот PR #190 https://github.com/gost-engine/engine/pull/190 был первым в серии изменений функции streebog и затрагивал исключительно только один аспект - устранение излишнего использования промежуточных буферов памяти при обработке входных данных функции streebog. Сложно было от этого заметить сколько-нибудь существенного изменения в синтетическом тесте, проводимом в обычных (не под высокой нагрузкой на шину данных и процессорный кеш ). В большей степени на результаты могло повлиять то, как компилятор обработал эти изменения и создал результирующй код. Если при этом сравнительное тестирование показало значимое падение скорости, нужно дополнительное внимание к параметрам компиляции и используемому компилятору. Во всяком случае мне не удалось выявить такого падения. Разброс показаний скорости выполнения алгоритма до и после , в бОльшей степени вызван случайными факторами . Вот данные полученные в серии прогонов , сравниваются черным - базовая реализация, синим - с применением патча.

https://user-images.githubusercontent.com/27359066/71379638-147da480-25dd-11ea-8022-8f376b85002d.png .

С какой целью были внесены эти изменения. Изменение нужно было для следующего шага - использование возможностей CPU архитектуры x86 эффективно читать 128бит невыровненные данные + задействование SSE2 оптимизированных инструкций для выполнения LPS преобразования алгоритма streebog. Это раскрывает потенциал современных CPU построенных на этой архитектуре и дает заметный прирост в скорости. Для SIMD оптимизаций я использовал практически без изменения уже имеющийся в кодовой базе, но по какой-то причине выключенный из сборки, gosthash2012_sse2.h - реализацию Дегтярева. Изменения в PR сделаны с учетом того ,чтобы избежать негативного влияния на производительность для прочих архитектур, не реализующих SSE и неспособных читать невыровненные данные. Но этот момент требует отдельной проверки. Я не имею возможности провести качественный тест на широком круге архитектур. (отмечу, что travis CI проходит все тесты для x86_64/ppc/aarch64 для linux/osx собранные gcc/clang , но опираться на скоростные покатели при выполнении в среде travis нельзя)

Привожу тесты для x86_64, полученные по итогам применения тех изменений, которые касаются streebog.

Intel Core i5-4210U CPU @ 1.70GHz Linux x86_64 GNU/Linux

compare streebog digest calculation

github.com/gost-engine/engine @09615031fffa93d7b42af7ad1029d963445c7c74

GOST-R 34.11-2012(512). block size / digest speed, MBps /size 32 64 256 1024 8192 9732 65536

   1      6.83     11.18     26.80     40.96     46.02     43.10     41.69
   2      5.45     11.47     27.70     41.38     48.18     48.54     47.43
   3      7.19     11.55     27.50     41.05     48.20     48.45     47.10
   4      7.48     11.51     28.26     41.35     47.46     49.62     48.27
   5      7.52     11.69     27.70     42.30     48.75     49.36     50.12

github.com/ddulesov/engine @e8b84331c31fb38f2eed437f4675633b846e0f3e

GOST-R 34.11-2012(512). block size / digest speed, MBps /size 32 64 256 1024 8192 9732 65536

   1     13.58     22.38     55.46     87.51    100.05    103.75     98.60
   2     12.70     20.12     53.74     86.84    102.69    103.32    105.44
   3     13.70     21.90     55.48     87.48    102.09     91.67    104.02
   4     13.64     21.16     49.96     86.11    101.11    103.12     99.33
   5     13.38     21.64     54.34     84.41    102.17     90.81     99.52

в обоих случаях сборка производилась так

cmake -DOPENSSL_ROOT_DIR=${PREFIX} -DOPENSSL_LIBRARIES=${PREFIX}/lib -DOPENSSL_ENGINES_DIR=${PREFIX}/lib/engines-1.1 .. && make

gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

на базе OpenSSL 1.1.1e github.com/openssl/openssl/tree/OpenSSL_1_1_1-stable @c8943eb04ae41506ec8a1869103e2e1dec6bfcd8

platform: linux-x86_64 options: bn(64,64) rc4(16x,int) des(int) idea(int) blowfish(ptr) compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG

Это показывает, что для архитектуры x86_64 задействование SIMD дает практически *100% увеличение скорости работы** функции streebog-hash.

И второе. Все это синтетические тесты, которые весьма далеки от реального использования алгоритма. Тестовые данные кратны 64 байт, то есть размеру блока данных алгоритма streebog. В этом случае при выполнении исключается ветка алгоритма, выполняющая паддинг данных. В реальных условиях данные могут быть любой длины. Давайте сравним результаты прикладного теста. В наборе утилит есть gost12sum, которая выполняет вычисление и сравнение хеш-сумм файлов. В форкнутой версии я добавил утилиту gost1sum с той же функциональностью. При выполении проверки хеш-сумм этими утилитами основное время затрачивается алгоритмом вычисления хеша. Для тестирования можно использовать любой набор файлов общим объемом от 1Гб. В этом случае уменьшается влияние случайных факторов. Для уменьшения влияния кеширования данных в ядре Linux тесты лучше повторить несколько раз.

Создаем check-file

find /path_to_files(>1Gb) -type f -exec ./bin/gost12sum -v {} \; > .check

сравниваем время проверки хеш сумм

из upstream github.com/gost-engine/engine

time ./bin/gost12sum -c .check

из github.com/ddulesov/engine

time ./bin/gost1sum -c .check

Я не привожу свои данные . Предлагаю всем участникам обсуждения выполнить это сравнительное тестирование на доступных платформах. Мне было бы интересно взглянуть на результаты выполнения на Эльбрус и многопроцессорных aarch64 .

было бы круто дотащить результаты бенчмарков в wiki

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

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/gost-engine/engine/issues/198?email_source=notifications&email_token=AAQ5KUFMWTVJLS53XQ3FONLQ727WPA5CNFSM4KDEGJ52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJ7FD5I#issuecomment-578703861, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ5KUH6GQ6UDLSV2J2NOFLQ727WPANCNFSM4KDEGJ5Q .

ddulesov commented 4 years ago

Я не спорю, что это полезная утилита, но use case у неё 0.01%.

Да, согласен. В основном из-за того что криптографические хэши и стрибог в том числе медленные и не подходят для этих задач. Здесь лучше работают специализированные, blake3 например. Но раз утилита включена в состав утилит gost , я решил адаптировать наш вариант под стрибог.

ddulesov commented 4 years ago

Если не затруднит, проведите сравнительное тестирование gost12sum и gost1sum в режиме проверки хэш-сумм по массиву файлов объемом от 1Гб. любопытно посмотреть на эти цифры

Чтоб убедиться, что параллельный подсчет быстрее однопоточного и поразиться этому?

Да. И соглашусь с возражением, что такое сравнение сейчас несет исключительно академический интерес. Текущая архитектура openssl , к сожалению, не позволяет сейчас задействовать параллельные вычисления, в том числе во внешних модулях. Насколько я знаю, даже планируемые изменения связанные с внедрением т.н провайдеров не предусматривают этого. @beldmit Насколько тесно вы сотрудничаете с лидерами openssl comunity и можете повлиять на принятие решений в будущей версии openss 3.0 ? Можно ли через вас протолкнуть ряд изменений. При изучении возможности повышения быстродействия реализаций streebog и кузчечик на arm и под avx512 в gost-engine я столкнулся с рядом ограничений. В частности, выделение памяти под структуры данных производится во внутренних функциях openssl и выполняется через вызов malloc (OPENSSL_malloc ). А это значит, что нет возможности указать требуемое выравнивание, которое необходимо для работы arm neon и avx512. Не планирует ли команда openssl какие-то изменения, связанные с этим?

ddulesov commented 4 years ago

Да, Ваш вариант на 6% быстрее

Это только x86. Я думаю не только мне интересно оценить влияние изменений на aarch64, ppc , а точнее отсутствие снижения скорости.

beldmit commented 4 years ago

Для aarch64 у меня есть коммерческая реализация, которая даёт примерно трёхкратное ускорение, на тамошних интринсиках.

beldmit commented 4 years ago

При изучении возможности повышения быстродействия реализаций streebog и кузчечик на arm и под avx512 в gost-engine я столкнулся с рядом ограничений. В частности, выделение памяти под структуры данных производится во внутренних функциях openssl и выполняется через вызов malloc (OPENSSL_malloc ). А это значит, что нет возможности указать требуемое выравнивание, которое необходимо для работы arm neon и avx512. Не планирует ли команда openssl какие-то изменения, связанные с этим?

Насколько я знаю, не планирует.

ddulesov commented 4 years ago

@adegtyarev, Лёша, можно тебя попросить или засабмитить твои наработки по sse4 патчем сюда, или разрешить позаимствовать?

@beldmit sse4.1 и sse2 Дегтярева по сути своей не отличаются и используют один план. Не стоит ожидать сколько-нибудь заметного роста скорости от sse4. Причина этого лежит в сути алгоритма стрибог - перестановки блоков по 64 бита с использованием внешней таблицы. Это часть алгоритма самая тяжелая и не может быть векторизована.

В свое время, экспериментируя со стрибог , я пытался задействовать avx2 instructions set. avx оперирует уже 256 бит данными по сравнению с 128бит sse4. И вроде бы это обстоятельство должно было дать прирост в скорости. Оказалось, что то небольшое ускорение, которое дает увеличение разрядности регистров и выполнение арифметических и логических операций над ними теряется на фоне прочих, выполняющих перестановки. У меня получилось добиться примерно 7% прироста, но ценой полного переписывания кода на assembler. Еще небольшой потенциал этом плане есть у avx512 . разрядность регистров 512 бит позволяет хранить переменные streebog по одному на каждый регистр и выполнять xor над ними как одно целое, исключая split-gather операции. Но тут нас ждет проблема с другой стороны. avx512 требует 32 байт выравненной памяти. А поскольку openssl не управляет выравниванием, и gost-engine располагает свои структуры в блоках памяти , выделяемых openssl , но нет гарантии, что он будет соответствовать требованиям процессора . Иначе мы случайно будем ловить segfault GP error. Обойти сейчас это можно только триком. запрашиваем блок на 32 байта больше и на стороне gost-engine делаем выравнивание. Это усложнит код, сделает его менее поддерживаемым. Хотя, такой подход имеет место. Но стоит ли ради +10% только для небольшой доли архитектур?