2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AVX/AVX2/AVX512Advent Calendar 2021

Day 19

AVX/AVX2による整数型から浮動小数点型への型変換

Last updated at Posted at 2021-12-18

はじめに

浮動小数点型であるfloat/double型から整数型に変換します.
変換には,cvt命令とcvtt命令があります.
cvt命令は,MXCSRレジスタに応じて丸めを行い,cvtt命令は,常に切り捨てで丸めを行います.

_mm256_cvtepi32_ps (AVX)

__m256 _mm256_cvtepi32_ps (__m256i a)
asm: vcvtdq2ps ymm, ymm/m256

動作
cvtepi32_ps
v1_32.png
CPI/Uops

Architecture Latency Throughput Uops
Alderlake 4 0.5 -
Icelake 4 0.5 1
Skylake 4 0.5 1
Broadwell 3 1 1
Haswell 3 1 1
Ivy Bridge 3 1 1
Sandy Bridge 3 1 1
Zen3 3 0.5 1
Zen2 3 1 1
Zen 4 2 2
  • メモリから読み込んでもスループットは変わりません.

説明

8つの要素のintをfloatに変換します.

型を変換するだけですが,演算コストがかかります.
IntelのCPUの場合,Alderlakeを除いて浮動小数点の加算と同じコストがかかります.
AMDの場合,Zen2までは加算よりもすこしだけ重たい処理になります.
intからfloat変換はメモリからロードしてもスループットは変わりません.

_mm256_cvt|cvttps_epi32 (AVX)

__m256i _mm256_cvtps_epi32 (__m256 a)
asm: vcvtps2dq ymm, ymm/m256
__m256i _mm256_cvttps_epi32 (__m256 a)
asm: vcvttps2dq ymm, ymm/m256

動作
cvtps_epi32/cvttps_epi32
v1_32.png
cvt_32_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 4 0.5 -
Icelake 4 0.5 1
Skylake 4 0.5 1
Broadwell 3 1 1
Haswell 3 1 1
Ivy Bridge 3 1 1
Sandy Bridge 3 1 1
Zen3 3 0.5 1
Zen2 3 1 1
Zen 4 2 2
  • 逆変換とパフォーマンスは同じです.
  • メモリから読み込んでもスループットは変わりません.

説明

8つの要素のfloatにint変換します.

cvt命令の場合,intへの変換の場合,MXCSRコントロールレジスタの状態に合わせて浮動小数点を丸めます.
cvtt命令の場合,MXCSRコントロールレジスタの状態を無視して,常時0への切り捨てのキャストします.
つまり下記のようなキャストを行います.

double a=10.5;
int b = (int)a;

打ち切る場合も,打ち切らない場合もパフォーマンスは同じで,この逆変換とも同じです.
IntelのCPUの場合,Alderlakeを除いて浮動小数点の加算と同じコストがかかります.
AMDの場合,Zen2までは加算よりもすこしだけ重たい処理になります.

_mm256_cvtepi32_pd (AVX)

__m256d _mm256_cvtepi32_pd (__m128i a)
asm: vcvtdq2pd ymm, xmm/m128

動作

cvtepi32_pd
cvt_32_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 7 1 -
Icelake 7 1 2
Skylake 7 1 2
Broadwell 6 1 2
Haswell 6 1 2
Ivy Bridge 5 1 2
Sandy Bridge 5 1 2
Zen3 4(≤11) 1(0.5) 2(1)
Zen2 4(≤11) 1(1) 2(1)
Zen 7(≤14) 2(3) 4(7)
  • floatへの変換よりも重たいです.
  • かっこつきはメモリから読み込んだ場合です.
  • AIDA64: Zen L:7, T:2, Zen2 L:4, T:1, Zen3 L:4, T:0.5
  • Anger: Zen L:6, T:2, Zen2 L:5, T:1, Zen3 L:6, T:1
  • uopsによると,メモリから読み込むとZen3のスループットは倍になります.
  • IntelのCPUは,doubleからintへの変換も同コストです.

説明

4つの要素のintをdoubleに変換します.
doubleとintのサイズが異なり,出力は2倍のサイズとなるため,引数の型は__m128iです.
epi64からの変換ではないことに注意してください.

_mm256_cvtpd|cvttpd_epi32 (AVX)

__m128i _mm256_cvtpd_epi32 (__m256d a)
asm: vcvtpd2dq ymm, ymm/m256
__m128i _mm256_cvttpd_epi32 (__m256d a)
asm: vcvttpd2dq ymm, ymm/m256

動作

cvtpd_epi32/cvttpd_epi32
cvt_64_32.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 7 1 -
Icelake 7 1 2
Skylake 7 1 2
Broadwell 6 1 2
Haswell 6 1 2
Ivy Bridge 5 1 2
Sandy Bridge 5 1 2
Zen3 6 1 2
Zen2 6 1 2
Zen 7 2 4
  • AIDA64 Zen L:7, T:1, Zen2 L:6.1, T:0.68 Zen3 L:6.5, T:0.43
  • メモリから読み込んでも動作は変わりません.

説明
下位4つの要素のdoubleにint変換します.

cvt命令の場合,intへの変換の場合,MXCSRコントロールレジスタの状態に合わせて浮動小数点を丸めます.
cvtt命令の場合,MXCSRコントロールレジスタの状態を無視して,常時0切り捨てのキャストします.
つまり下記のようなキャストを行います.

double a=10.5;
int b = (int)a;

doubleとintのサイズが異なり,出力は半分のサイズとなるため,戻り値の型は__m128iです.
epi64への変換ではないことに注意してください.

Zenアーキテクチャもスループットに違いはありません.

2
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?