カテゴリ:ソフト開発日誌
scankeylx を x86_64 (64bit) 対応にする作業のうち、「コンパイルできない」、「実行結果が異常になる」などのソースコードの記述に由来する問題は解消した。Raspberry Pi3 (ARMv7) 環境ではまだ要修正だ(放置しても大きな支障はない)。
64bit 対応すると実行速度が 1 割ほど低下する。scankeylx は複雑な演算はしていない。8bit と 16bit 単位の文字・パターン検索・操作が主なので CPU の語長が 32bit から 64bit になることは大きなメリットにもマイナスにもならない。厳密にいえば CPU - Memory 間のバンド幅は大きい方が良い。 生成されるオブジェクトコードの質なんだろうな... 気になるので良いオブジェクトコードが生成される様にソースを弄っていた。Free Pascal Compiler(FPC) 2.6.2-8 ではどうにもならない。最も高頻度に回るループ内側の処理を抜き出してみる。 FPC 2.6.2-8 で次のようなオブジェクトコードになった。r14d から eax に比較毎にレジスタ間転送が行われている。色々と書き換えてみて消せなかった。eax を使うのはソース上では cardianl 型変数を使っているからだ。byte 型変数にするとさらにコードは悪化する。 FPC 2.6.2-8 2944: 0f b6 03 movzbl (%rbx),%eax 2947: 41 89 c6 mov %eax,%r14d 294a: 44 89 f0 mov %r14d,%eax 294d: 83 f8 30 cmp $0x30,%eax 2950: 72 dc jb 292e <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xe6> 2952: 44 89 f0 mov %r14d,%eax 2955: 83 f8 73 cmp $0x73,%eax 2958: 77 d4 ja 292e <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xe6> 295a: 44 89 f0 mov %r14d,%eax 295d: 83 f8 39 cmp $0x39,%eax 2960: 0f 86 f7 02 00 00 jbe 2c5d <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x415> 2966: 44 89 f0 mov %r14d,%eax 2969: 83 f8 44 cmp $0x44,%eax 296c: 72 c0 jb 292e <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xe6> 296e: 44 89 f0 mov %r14d,%eax 2971: 25 df 00 00 00 and $0xdf,%eax 2976: 41 89 c6 mov %eax,%r14d 2979: 44 89 f0 mov %r14d,%eax 297c: 83 f8 44 cmp $0x44,%eax 297f: 74 25 je 29a6 <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x15e> 2981: 44 89 f0 mov %r14d,%eax 2984: 83 f8 4c cmp $0x4c,%eax 2987: 0f 84 1d 07 00 00 je 30aa <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x862> 298d: 44 89 f0 mov %r14d,%eax 2990: 83 f8 50 cmp $0x50,%eax 2993: 0f 84 f3 03 00 00 je 2d8c <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x544> 2999: 44 89 f0 mov %r14d,%eax 299c: 83 f8 53 cmp $0x53,%eax 299f: 75 8d jne 292e <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xe6> 29a1: e9 45 06 00 00 jmpq 2feb <SKLXTHSEARCH_TTHREADSEARCH_$__SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x7a3> うん、コンパイラを変えよう。Ubuntu 16.04 で FPC 3.0.0 を使ってみる。ソースを書き換えて byte 型変数を使ったところで、「こんなオブジェクトコードになるはずだよな」に近いコードになった。 FPC 3.0.0 e0: 44 8a 33 mov (%rbx),%r14b e3: 41 80 fe 30 cmp $0x30,%r14b e7: 72 e3 jb cc <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xcc> e9: 41 80 fe 73 cmp $0x73,%r14b ed: 77 dd ja cc <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xcc> ef: 41 80 fe 39 cmp $0x39,%r14b f3: 0f 86 8a 02 00 00 jbe 383 <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x383> f9: 41 80 fe 44 cmp $0x44,%r14b fd: 72 cd jb cc <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xcc> ff: 44 88 f0 mov %r14b,%al 102: 24 df and $0xdf,%al 104: 41 88 c6 mov %al,%r14b 107: 41 80 fe 44 cmp $0x44,%r14b 10b: 74 1f je 12c <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x12c> 10d: 41 80 fe 4c cmp $0x4c,%r14b 111: 0f 84 7f 06 00 00 je 796 <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x796> 117: 41 80 fe 50 cmp $0x50,%r14b 11b: 0f 84 7e 03 00 00 je 49f <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x49f> 121: 41 80 fe 53 cmp $0x53,%r14b 125: 75 a5 jne cc <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0xcc> 127: e9 9f 05 00 00 jmpq 6cb <SKLXTHSEARCH$_$TTHREADSEARCH_$__$$_SEARCHMAIN$PBULKBUFFER$$BOOLEAN+0x6cb> 普通にレジスタ割り付けができて、ほぼ冗長な転送を消す最適化が行われていた。ff..104 の間の演算に冗長な部分が残る。演算結果を al に必ず保持する強いルールがある? Ubuntu 16.04 でコンパイルしたコードは Ubuntu 12.04 では動かない。もう一つ壁を乗り越えないと。 お気に入りの記事を「いいね!」で応援しよう
最終更新日
2016.12.05 08:55:46
コメント(0) | コメントを書く
[ソフト開発日誌] カテゴリの最新記事
|
|