キッカケ
こちらに掲載されているMD5関数のテストプログラムを実行したところ、gcc on WSLでコンパイルすると頭一つ早い結果となった。(msvc/clangでは580 MB/s程度、gccでは約750 MB/s程度)
Windowsネイティブで同等の速度を出せないか試行錯誤をした。
「手段が目的」なので、単に自己満足だけである。
おそらく、全部MinGW環境を構築してビルドすれば、この投稿に書く内容はやる必要はないと思われる。
- cl.exe
Microsoft(R) C/C++ Optimizing Compiler Version 19.15.26729 for x86 - clang-cl
Microsoft(R) C/C++ Optimizing Compiler Version 19.15.26729 for x86 - clang on WSL
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) - gcc on WSL
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
msvcで試行錯誤してみたが
結論から言うとオプションを変えても、目立った効果はなかった。
/Oy /Ot /Ob2 /Oi /O2
WSL(Ubuntu16.04)でクロスコンパイル
gccでビルドして、Intel記法でアセンブル出力する。
sudo apt install g++-mingw-w64-i686
i686-w64-mingw32-gcc-win32 md5.c -O3 -fomit-frame-pointer -S -masm=intel -fstack-protector
Visual Studio に組み込む
クロスコンパイルで作成された*.SファイルをWindowsに持ってきて、Visual Studioのプロジェクトに組み込む。
アセンブリファイルをビルド出来るようにする。
こちらを参考にした。
- [ビルドのカスタマイズ]をクリックする。
- [masm(.targets, .props)]を選択する。
- ビルドのカスタマイズで 追加した*.sファイルの項目の種類を
Microsoft Macro Assembler
に変更する。
これだけだとビルドしたときにエラー(C++ LNK2026 モジュールは SAFESEH イメージには安全ではありません
)が発生して、リンクできない。
*.sファイルのプロパティで、[Microsoft Macro Assembler] - [Advanced]の Use Safe Exception Handlersをはい(/safeseh)
に変更する。
アセンブリファイルのディレクティブなどを編集する
そのままだとMASMで解釈できないディレクティブがあるので、
関数名のラベルとそれより前と、ret
の後をMASM用に差し替える。
アセンブラは詳しく無いので、cl.exeの/FAcs
の出力結果からほぼコピペしている。
今回対象にした関数は処理しかかなったが、データ割当などがあるとコピペはできないと思われる。
diff U5b md5.s md5_compress.s
--- md5.s Mon Sep 17 12:29:36 2018
+++ md5_compress.s Mon Sep 17 12:40:48 2018
@@ -1,15 +1,21 @@
- .file "md5.c"
- .intel_syntax noprefix
- .section .text.unlikely,"x"
-LCOLDB0:
- .text
-LHOTB0:
- .p2align 4,,15
- .globl _md5_compress
- .def _md5_compress; .scl 2; .type 32; .endef
-_md5_compress:
+ .686P
+ .XMM
+ include listing.inc
+ .model flat
+
+INCLUDELIB MSVCRT
+INCLUDELIB OLDNAMES
+
+PUBLIC _md5_compress
+EXTRN @__security_check_cookie@4:PROC
+EXTRN _memcpy:PROC
+EXTRN _memset:PROC
+EXTRN ___security_cookie:DWORD
+_TEXT SEGMENT
+
+_md5_compress PROC
push ebp
push edi
push esi
push ebx
sub esp, 64
@@ -622,10 +628,8 @@
pop ebx
pop esi
pop edi
pop ebp
ret
- .section .text.unlikely,"x"
-LCOLDE0:
- .text
-LHOTE0:
- .ident "GCC: (GNU) 5.3.1 20160211"
+_md5_compress ENDP
+_TEXT ENDS
+END