AVX-512の対応について
furafura 2022/12/03(Sat) 10:57
お世話になっております。
最近、SkayLake-XでのAVX-512でプログラムしております。
SIMD組み込み関数はとても苦手なので、MASMを用いています。
質問としてはMASMは関係ありません。
C++記述のみでポインタを用いてお示し出来た内容ですが御容赦下さい。
以下、実際の処理内容とは違って簡易となっております。
<C++側>
............
extern "C" {
void AVX512_TEST(LPBYTE dst);
}
............
Image img(64, 64); /* 展開メモリ確保 */
AVX512_TEST((LPBYTE)img.data());
............
<MASM側>
............
PUBLIC AVX512_TEST
AVX512_TEST PROC
(1) vmovdqu64 [RCX],zmm18 ; rcx = 第一引数
(2) vmovdqa64 [RCX],zmm18 ; ... 64byte境界の開始アドレスではない時は書き込み時に例外が発生。
ret
AVX512_TEST ENDP
............
<MASM側>(2)行のコメントにあります通り、
Imageクラスのdata()のアドレスではAVX-512の命令によっては適さない場合があります。
data()の実体はArray.ippなのかと推測します。
具体的に私が作っているのは、大量のY成分のみの画像データからImageに適合したRGBAに変換する処理でして、現状は(1)の命令にて速度的に許容出来ている段階です。
https://speakerdeck.com/cygames/marutihuratutohuomuhuan-jing-teshi-xian-surullvm-clangniyorusimdzi-dong-hekutoruzui-shi-hua?slide=37
ですが、このような資料もありましたもので、いずれ何か対応方法があればと思いまして、今後もopenSiv3Dでは公式未対応、或いはAVX-512での動作保証はない等、情報をいただけましたら幸いです。
(自分専用プロジェクトではAVX-512でコンパイルしていますが、特に問題を経験していません)
Reputeless 2022/12/04(Sun) 02:07
furafura 2022/12/06(Tue) 19:56
私の頭が固いので、返信にお時間を頂きまして申し訳ありませんでした。
仰るとおり、教えていただいた方法が1つあると思います。
かといってメモリコピーのコストが生じるぐらいならMASMは使わないです。
開始アドレスが32バイト境界で領域の大きさが128バイトだった場合、前後32をvmovdqu、間64バイトをvmovdqaとする。(例えばhttps://www.agner.org/optimize/ のSubroutine library内memcpy64.asmでやっているような感じ)
今は、既に私が行っている対応であるvmovdquの利用で行く事にします。(実際には4K画像ぐらいを相手にするため、おそらくコピー操作が2回生じるよりは良いでしょうし)
境界制御という意味では、メモリの管理は自前になったとしても、Texture(Image)だけでなく、Texture(char *, width, higeht)的なものがあるとありがたいと感じております。
Reputeless 2022/12/06(Tue) 23:49
furafura 2022/12/07(Wed) 00:40
ご配慮ありがとうございます。
繰り返しにつきましては、実は試してあります。
# include <Siv3D.hpp>
alignas(64) Image image2(3840,2160);
void Main()
{
while (System::Update())
{
void* test = (void*)image2.data();
int32 h = (int32)test;
Print(test);
if ((h & 0x3F) != 0) {
image2.release();
image2.resize(3840, 2160);
}
else {
break;
}
}
}
プログラムが間違いでなければ、私の環境だとデバッグモードではすぐ終了しますが、リリースモードではずっと表示が変化・更新され続けました。要するに巧く行きませんでした。