[Lazarusでx64 SIMD命令を使ってみる]で 実際にどれくらい処理時間が短縮出来るかuRDTSC.pas(37)を作ってみた
!uRDTSC.pas(37)
- 使用目的
・この関数は全体の何割を消費してるか知りたい ・この処理は現在何クロックを消費してるか知りたい という趣味の領域が目的です
- 使用方法
測定したい処理全体の先頭で startRDTSC; 測定したいユニットの先頭で RDTSCst(dtTSC[n]); 測定したいユニットの終了で RDTSCed(dtTSC[n]); .... 測定したい処理全体の終了 endRDTSC; この時点で結果はクリップボードに出力されます ユニットには名前を付けておけます dtTSC[n].name='func1'; なくても問題ない nは0〜9の数字でユニットを識別 つまり最大10個のユニットを識別出来ます(増やすならTSCtimerSizeを修正) パフォーマンスチェックの都度、入れたり外したりが面倒なら 関数の先頭で |$IFDEF enTSC}RDTSCst(dtTSC[0]);{$ENDIF} のように入れて 終了で |$IFDEF enTSC}RDTSCed(dtTSC[0]);{$ENDIF} と入れます。enTSC をコンパイル時に入れなければこれらは外れます 関数の先頭は常に同じ場所を通りますが、exitやraiseがあると入れ忘れる場合もあるでしょう その場合は処理時間が少な目に出るので stcntとedcntのカウント値で確認出来ます また意図的に途中終了の比率を確認する事にも使えるでしょう
結果を自分で表示処理したい場合は endRDTSC;をendRDTSC(false);として、その後でdtTSC配列を確認して下さい
- 作者:裏目小僧
- 利用はご自由に。
- Lazarus2.2.4 32bit/64bit Delphi5 Delphi 10.4.2である程度動作する事を確認しています
- Delphiで利用するにはUTF8からの文字コード変換が必要です
[Lazarusでx64 SIMD命令を使ってみる]でのSIMD命令の効果
startRDTSC; dtTSC[0].name:='for文による場合' ; dtTSC[1].name:='AVXによる場合' ; dtTSC[2].name:='SSEによる場合' ; RDTSCst(dtTSC[0]); for j := low(test1S) to High(Test1S) do test1D[j] := test1D[j] + coff * test1S[j]; RDTSCed(dtTSC[0]); canUSEAVX:=true; RDTSCst(dtTSC[1]); AVXcoffSum(test2D[0], test2S[0], coff, length(test2D)); RDTSCed(dtTSC[1]); canUSEAVX:=false; RDTSCst(dtTSC[2]); AVXcoffSum(test3D[0], test3S[0], coff, length(test3D)); RDTSCed(dtTSC[2]); endRDTSC; 配列の大きさは256個です
実行結果は
no | cyc | 全体の | st回数 | ed回数 | ed/st | name |
---|---|---|---|---|---|---|
0 | 2218 | 54.18 | 1 | 1 | 100.00 | for文による場合 |
1 | 720 | 17.59 | 1 | 1 | 100.00 | AVXによる場合 |
2 | 762 | 18.61 | 1 | 1 | 100.00 | SSEによる場合 |
4094 |
- AVXの書き方が悪いのかSSEの4並列に比べて8並列なのに、あまり速度は上がらない
- 配列サイズ256程度では効果がないのか
- 同じ関数を呼んでるのでキャッシュの影響なのか
という事で 2番目と3番目を入れ変えると
no | cyc | 全体の | st回数 | ed回数 | ed/st | name |
---|---|---|---|---|---|---|
0 | 2556 | 55.52 | 1 | 1 | 100.00 | for文による場合 |
1 | 366 | 7.95 | 1 | 1 | 100.00 | AVXによる場合 |
2 | 864 | 18.77 | 1 | 1 | 100.00 | SSEによる場合 |
4604 |
プライバシーポリシー本文は日本語以外に翻訳禁止 click寄付