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
Image の画像データ (Array<Color>) の最低アライメントは、64-bit 環境で 16 バイトです。
アライメントの情報は型に含まれるため、それを容易に 64 バイトに変更することができません。

Memory.hpp にアライメント関連の機能があります。
AlignedMalloc<Color, 64>(sizeof(Color) * 64 * 64) でアライメントされたメモリ領域を確保し、そこに Image の内容をコピーするなどして SIMD 処理を行う方法があります(コピーのコストは生じます)
編集
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
うまくいくかわかりませんが、理想のアライメントの Image ができるまで、何度か Image の作成と .release() を繰り返してみるのはどうでしょう。

OpenSiv3D としては、v0.8 で Image の画像データの最低保証アライメントを 32 あるいは 64 バイトにできないか調査・検討してみます。
また、const void* からの Texture 作成は良いアイデアだと思うので、同じく v0.8 での導入を検討します。
編集
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;
}
}
}
プログラムが間違いでなければ、私の環境だとデバッグモードではすぐ終了しますが、リリースモードではずっと表示が変化・更新され続けました。要するに巧く行きませんでした。
編集
Reputeless  2022/12/16(Fri) 21:36
情報提供ありがとうございます。こちらの環境でも再現できました。
根本的な解決には API 変更が必要という結論です。
v0.8 における Image 実装時に検討します。
編集
件名
Re: AVX-512の対応について
名前
コメント
画像添付


投稿修正キー (投稿を修正する時に使います)
画像認証 (右画像の数字を入力) 投稿キー

- WEB PATIO -