はじめに
小さい型から大きい型へ整数型・整数型変換をします.
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
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
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
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
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へ置き換えてペナルティを回避します.