LoginSignup
2
2

More than 1 year has passed since last update.

AVX/AVX2による整数型から整数型への型変換

Last updated at Posted at 2021-12-17

はじめに

小さい型から大きい型へ整数型・整数型変換をします.
char型,unsigned char型,short型,unsigned short型,int型,unsigned int型から,short型,int型,long long型に変換します.

unsignedな型への変換はありません.
また,大きい型から小さい型への変換がないことに注意してください.
小さい型への変換は,AVX2では,packs,packusで行います.

下記変換はAVX-512をサポートするシステムでしか使用できません.

  • 大きな整数から小さな整数への変換
  • epuへの変換
  • epi64/epu64からの変換(整数・double変換はepi32から)

_mm256_cvtepi8|epu8_epi16|epi32|epi64 (AVX2)

__m256i _mm256_cvtepi8_epi16 (__m128i a)
__m256i _mm256_cvtepu8_epi16 (__m128i a)
__m256i _mm256_cvtepi8_epi32 (__m128i a)
__m256i _mm256_cvtepu8_epi32 (__m128i a)
__m256i _mm256_cvtepi8_epi64 (__m128i a)
__m256i _mm256_cvtepu8_epi64 (__m128i a)
asm: vpmovsxbw ymm, xmm/m128 //epi8_epi16
asm: vpmovzxbw ymm, xmm/m128 //epu8_epi16
asm: vpmovsxbd ymm, xmm/m128 //epi8_epi32
asm: vpmovzxbd ymm, xmm/m128 //epu8_epi16
asm: vpmovsxbq ymm, xmm/m128 //epi8_epi64
asm: vpmovzxbq ymm, xmm/m128 //epu8_epi64

動作

cvtepi8_epi16
cvt_8_16.png

cvtepi8_epi32
cvt_8_32.png

cvtepi8_epi64
cvt_8_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 1 0.5 -
Icelake 3 1 1
Skylake 3 1 1
Broadwell 3 1 1
Haswell 3 1 1
Zen3 4(≤9) 1.25(0.5) 2(1)
Zen2 4(≤9) 1.15(0.5) 2(1)
Zen 2 2 3
  • 大きいサイズへの整数・整数型変換のパフォーマンスはすべて同じです.
  • Intel CPUはAlderlakeで高速化しています.
  • Zen2, Zen3の括弧付きはメモリからのロードを表し,メモリから__m128を読み込みながら変換する場合にスループットが倍になります.

説明

  • epi16: 16個の8ビット整数を16ビット整数に変換します.
  • epi32: 下位8個の8ビット整数を32ビット整数に変換します.
  • epi64: 下位4個の8ビット整数を64ビット整数に変換します.

epiは符号有り8bit,epuは符号無し8ビット整数を変換します.
変換先がepuになる変換は有りません.

_mm256_cvtepi16|epu16_epi32|epi64 (AVX2)

__m256i _mm256_cvtepi16_epi32 (__m128i a)
__m256i _mm256_cvtepu16_epi32 (__m128i a)
__m256i _mm256_cvtepi16_epi64 (__m128i a)
__m256i _mm256_cvtepu16_epi64 (__m128i a)
asm: vpmovsxwd ymm, xmm/m128 //epi16_epi32
asm: vpmovzxwd ymm, xmm/m128 //epu16_epi32
asm: vpmovsxwq ymm, xmm/m128 //epi16_epi64
asm: vpmovzxwq ymm, xmm/m128 //epu16_epi64

動作

cvtepi16_epi32
cvt_16_32.png

cvtepi16_epi64
cvt_16_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 1 0.5 -
Icelake 3 1 1
Skylake 3 1 1
Broadwell 3 1 1
Haswell 3 1 1
Zen3 4(≤9) 1.25(0.5) 2(1)
Zen2 4(≤9) 1.15(0.5) 2(1)
Zen 2 2 3
  • 大きいサイズへの整数・整数型変換のパフォーマンスはすべて同じです.
  • Intel CPUはAlderlakeで高速化しています.
  • Zen2, Zen3の括弧付きはメモリからのロードを表し,メモリから__m128を読み込みながら変換する場合にスループットが倍になります.

説明

  • epi32: 8個の16ビット整数を32ビット整数に変換します.
  • epi64: 下位4個の16ビット整数を64ビット整数に変換します.

epiは符号有り16bit,epuは符号無し16ビット整数を変換します.
変換先がepuになる変換は有りません.

_mm256_cvtepi32|epu32_epi64 (AVX2)

__m256i _mm256_cvtepi32_epi64 (__m128i a)
__m256i _mm256_cvtepu32_epi64 (__m128i a)
asm: vpmovsxdq ymm, xmm/m128 //epi32_epi64
asm: vpmovzxdq ymm, xmm/m128 //epu32_epi64

動作

cvtepi32_epi64
cvt_32_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 1 0.5 -
Icelake 3 1 1
Skylake 3 1 1
Broadwell 3 1 1
Haswell 3 1 1
Zen3 4(≤9) 1.25(0.5) 2(1)
Zen2 4(≤9) 1.15(0.5) 2(1)
Zen 2 2 3
  • 大きいサイズへの整数・整数型変換のパフォーマンスはすべて同じです.
  • Intel CPUはAlderlakeで高速化しています.
  • Zen2, Zen3の括弧付きはメモリからのロードを表し,メモリから__m128を読み込みながら変換する場合にスループットが倍になります.

説明
4個の32ビット整数を64ビット整数に変換します.

epiは符号有り32bit,epuは符号無し32ビット整数を変換します.
変換先がepuになる変換は有りません.

_mm256_cvtsi256_si32|si64 (AVX)

//long long
__int64 _mm256_cvtsi128_si64 (__m256i a)
__int64 _mm_cvtsi128_si64 (__m128i a)
__int64 _mm_cvtsi128_si64x (__m128i a)
asm: movq r64/m32, xmm
//int
int _mm256_cvtsi256_si32 (__m256i a)
int _mm_cvtsi128_si32 (__m256i a)
asm: movd r32/m32, xmm

動作

_mm256_cvtsi256_si64
cvt_64_1.png

_mm256_cvtsi256_si32
cvt_32_1.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake mem. dep. 0.5 -
Icelake ≥3(11) 1(0.5) 1(2)
Skylake ≥3(10) 1 1(2)
Broadwell ≥1(9) 1 1(2)
Haswell ≥1(9) 1 1(2)
Ivy Bridge ≥1(9) 1 1(2)
Sandy Bridge ≥1(9) 1 1(2)
Zen3 ≥5(10) 1 1
Zen2 ≥5(9) 1 1
Zen ≥5(8) 1 1
  • 括弧付きはメモリへの書き出しの場合に変化した数値です.
  • Icelakeはメモリへの書き出しスループットが倍です.

説明
下位32/64ビットの整数1つを,整数レジスタもしくはメモリにコピーします.
xmmレジスタに出力するわけではありません.
_mm_cvtsi128_si64はスカラ演算用の命令で,SSE2から使えます.

AVX命令である下記はSSE命令のマクロ展開でしかありません.

int _mm256_cvtsi256_si32 (__m256i a)
asm: vmovd r32, xmm
#define _mm256_cvtsi256_si32(a) (_mm_cvtsi128_si32(_mm256_castsi256_si128(a)))

なお,Visual Studioだと下記命令もマクロ展開されていますが,公式には下記AVX命令はありません.

#define _mm256_cvtsi256_si64(a) (_mm_cvtsi128_si64(_mm256_castsi256_si128(a)))

コンパイラは,SSE命令であるmovq,movdを,周囲の命令の状態に応じてAVX命令であるvmovq,vmovdへ置き換えてペナルティを回避します.

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