LoginSignup
2
1

More than 1 year has passed since last update.

AVX/AVX2によるキャスト

Last updated at Posted at 2021-12-16

はじめに

型に関するcastについて説明します.

Cast

この命令は,C++でのreinterpret_cast相当であり,データの示す型だけキャストするもので,中の値を返還するものではありません.
演算を含まなく,コンパイル時にすべて解決するため,レイテンシ0の計算になります.

一方でstatic_castに相当する,格納する値も変更するようなその場合の命令はConvertにまとめられています.

つまり下記に示す例のように,(1)のように値を型に合わせて変換するものがconvertに相当し,後者の(2)のデータをそのままに保持する型をへ関するのがcastに相当します.

float val = 1.5;
int a = int(val);//(1)
int b = *(int*)(&val);//(2)

このキャストは,主に算術命令ではなくデータの並びを操作するような命令時に,その命令に適切な型がないときにキャストすることでコンパイルを可能にします.
算術演算とは違い,1番目の要素と2番目の要素を入れ替えるなどの操作などは型に依存しません.
例えば,__m256__m256iは整数と浮動小数点と入っている値は違いますが,__m256iに入っているものがintであれば,32ビットのビット列が8つづつ収まっている配列であるという概念は同じです.
そのため,データを入れ替える命令は,浮動小数点であっても整数であっても実行可能です.
AVX命令は,概ねその型にあった命令が用意されていますが,いくつかは用意されていません.
例えば,レジスタに1つの要素を代入するinsert命令は,整数命令しか十分な命令が用意されていません.
しかしながら,その命令はただキャストすれば同じように使うことができます.

下記に,全てのキャスト命令の一覧表を示します.
-は,自分自身へのキャストであるため意味がありません.xはその命令が存在しないことを示しています.
同サイズの型はすべて相互変換可能であり,また,サイズが異なるものに対しては,同種(m128とm256など)の変換だけ用意されています.つまり,同種にキャストしたのちに任意の型に更にキャストすれば,全ての場合に対応しています.
コンパイラへの指示であるため,どれだけネストしても速度が増えるということはありません.
また,mm128(d/i)から,mm256(d/i)への変換はYMMの値が未定義であるため,zextを付けた命令を呼ぶと0エクステンションした値としてキャスト可能です.

mm128 mm128d mm128i mm256 mm256d mm256i
mm128 - _mm_castpd_ps _mm_castsi128_ps _mm256_castps256_ps128 x x
mm128d _mm_castps_pd - _mm_castsi128_pd x _mm256_castpd256_pd128 x
mm128i _mm_castps_si128 _mm_castpd_si128 - x x _mm256_castsi256_si128
mm256 _mm256_castps128_ps256
_mm256_zextps128_ps256
x x - _mm256_castpd_ps _mm256_castsi256_ps
mm256d x _mm256_castpd128_pd256
_mm256_zextpd128_pd256
x _mm256_castps_pd - _mm256_castsi256_pd
mm256i x x _mm256_castsi128_si256
_mm256_zextsi128_si256
_mm256_castps_si256 _mm256_castpd_si256 -
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1