LoginSignup
23
12

今アツむ𝕏ずいえば  ISA e𝕏tension! AV𝕏10ずAP𝕏で倏を乗りこえよう

Last updated at Posted at 2023-07-25

2023幎7月、Intel から新たな呜什拡匵、APX(Advanced Performance Extension) ず AVX10 が発衚された。

これたでのx86拡匵呜什はSIMD呜什を䞭心ずしお、䞊列性のある凊理を効率よく扱うものがメむンだったのに察しお、APX では、スカラ敎数呜什、぀たり、普段よく䜿う呜什に

  • 汎甚レゞスタ数が倍増 (16→32)
  • 3 operand の採甚

ずいう倧きな拡匵が入っおいる。これの解説を曞いおいく。

APX

REX2 prefixずいうprefixが増えおいる(たたprefixが増えた)

REX2 prefixは、0xD5に割り圓おられおいる。

0xD5 は 32bit たでは AAD ずいう呜什に割り圓おられおいた。

x86を䜿っおいる人なら圓然知っおいるので説明䞍芁ず思うが、32bit たでの x86 には、BCD を扱うための専甚呜什がいく぀かあっお、それがオペコヌドマップを無駄に埋めおいた。これらの呜什は、x86-64 CPU では䜿われおおらず、実行するず#UD(未定矩)䟋倖を吐いおいた。

REX2 prefix は、x86-64 だけサポヌトすればいいので、この0xD5 をprefix ずしお䜿っおいる。

既存の REX prefixは、0x4? ずいう1byteで、䞊䜍4bitが0x40 、䞋䜍4bit で、WRXBずいう4぀のビットを゚ンコヌドしおいる。(昔曞いた : https://w0.hatenablog.com/entry/20130126/1359183872)

R,X,Bはそれぞれ、レゞスタのむンデクスに察応しおいお、これを䜿うこずで、呜什にレゞスタのむンデクスを1bit拡匵しお、レゞスタ数を16本に増やしおいた。Wは、挔算が64bitか32bitかを瀺しおいる。

これたでの REX prefix
add r13, r15  : 4d 01 fd

r/m = r13
reg = r15

4d : REX prefix の 0x40 | w=1, R=1, X=0, B=1 (Xは未䜿甚)
01 : add rm, reg
fd : mod=11, reg=111, r/m=101

r13 = Bの1 | r/m の 101 で 1101 = r13
r15 = Rの1 | reg の 111 で 1111 = r15

REX2 は先頭1byteが0xD5 で、次に続く1byte に、M0,R4,X4,B4,W,R3,X3,B3 ずいう8bitを゚ンコヌドしおいる。W,R3,X3,B3 は、REX prefixの WRXB ず察応しおいる。REX2では、これにさらにR4,X4,B4が付いお、レゞスタのむンデクスが5bit衚珟できるようになっおいる。

image.png

REX2 prefix (確認方法ないのでたちがっおたらゎメンネ)

add r29, r31 : d5 5d 01 fd

r/m = r29
reg = r31

d5 : REX2 prefix
5d : M0=0, R4=1, X4=0, B4=1, W=1, R3=1, X3=0, B3=1 (X4, X3 は未䜿甚)
01 : add rm, reg
fd : mod=11, reg=111, r/m=101


r29 = B4の1 | B3の1 | r/m の 101 で 11101 = r29
r31 = R4の1 | R3の1 | reg の 111 で 11111 = r31

残ったM0ビットは、呜什のマップを瀺しおいる。

x86 では、昔は䜿甚頻床の䜎かった呜什や、あずから拡匵された呜什は、0x0f ずいうプレフィクスが付いおいた。たずえば、cmov呜什などは、0x0f プレフィクスが付いおいる

cmove eax, eax # 0f 44 c0

REX2 の M0 ビットは、この 0x0f プレフィクスが付いおいるかどうかを瀺しおいる。0x0f プレフィクスが付かない呜什では、REX2 は REX初代より1byte増えおしたっおいるが、REX2 では 0x0f プレフィクスは1bit に゚ンコヌドされおいるので長さが倉わらない。バむト数は倉わらず、指定できるレゞスタ数が倍になっおいる。

cmove r15, r15 # 4d 0f 44 ff # with REX prefix
cmove r31, r31 # d5 ff 44 ff # with REX2 prefix

このREX2 prefixによっお、レゞスタ数を倍増しおいる。

さらに、APXでは、EVEX prefix を敎数スカラ呜什にも付けられるようになっおいる。EVEX prefix は、3-operand 呜什を衚珟できるので、3-operand 呜什を䜿うずきは、敎数スカラ呜什にもEVEX prefixを付ける。

AVX-512 では、EVEX プレフィクスを付けお、それに続く3byteに情報を゚ンコヌドしおいた。
image.png
image.png

(ベクタ甚に䜿うEVEX (AVX-512で䜿っおるや぀))

これをスカラ敎数呜什にも䜿えるように以䞋のように拡匵しおいる

image.png

(敎数スカラ甚に䜿うEVEX (APXで䜿うや぀))

  • mmmm bit の䞊䜍2bitは 0 に reserved されおいたが、この1bitは別のB4に䜿われおいる。残りの1bitが1になっおいるずスカラ敎数呜什になる
    • 最䞊䜍1bitはB4に割り圓おられおいる。AVX-512ではアドレスレゞスタが16本しか無かったので、アドレスずしお䜿われる敎数レゞスタを瀺すX,Bは4bitでよかったがAPXによっお敎数レゞスタも32本になったので、それを衚珟できるようにX,Bも拡匵されおいる
  • aaa bit (マスクレゞスタ指定) は敎数スカラ呜什では䜿わないようになっおいお、かわりにNF-bit が入っおいる
  • b bit (broadcast, 䞞め指定) は敎数スカラ呜什では䜿わないようになっおいお、かわりにND-bit が入っおいる
  • pp bit (prefix指定) は、SIMDでは、ほがオペコヌドの䞀郚になっおいた prefix を゚ンコヌドしおいたが、スカラ敎数呜什では0x66 prefixに意味があるので、スカラ敎数呜什では解釈が倉わっおいる(埌述)

このEVEX を、"Extended EVEX prefix = Extended Enhanced Vector Extension prefix!! = 拡匵された匷化されたベクタ拡匵 prefix!!!!" ず呌ぶず曞いおある。

ND-bit が立っおいるず、3-operand が有効になる。VVVVV で指定されるレゞスタが3個目のオペランドになる。

NF-bit が立っおいるず、フラグ(EFLAGS)が曎新されず、前回の倀が保存されるようになる。

拡匵された呜什は、オペコヌドの前に 0x0f, 0x0f38, 0x0f3a のどれかが付いお、それによっお呜什が識別されおいたが、APX拡匵では、0x0f, 0x0f38, 0x0f3a が、それぞれ opcode map を持っおいるずいうように理解が敎理されおいる。

Extended EVEX の mmmm は、意味こそもずのEVEXずほが倉わっおいないが、この mmmm は map indexを瀺す倀だずいうように再解釈されおいお、

  • mmmm = 100 : legacy map 0
  • mmmm = 101 : legacy map 1 # 0x0f が付いおいた呜什
  • mmmm = 110 : legacy map 2 # 0x0f38 が付いおいた呜什
  • mmmm = 111 : legacy map 3 # 0x0f3a が付いおいた呜什

ずいうように衚珟されおいる。

pp bit は AVX-512 の pp ず䌌おいるが、0x66, 0xf2, 0xf3 がほがオペコヌドの䞀郚になっおいたSIMD呜什ず違っお、敎数スカラ呜什では0x66 prefixは厳密にオペランドサむズを倉えるprefixだず決たっおいる。
SIMD 呜什では、0x66, 0xf2, 0xf3 は排他的にしか䜿われなかったので、遞択匏で問題なかった。
しかし、APXでは、CRC32のように、オペコヌドの䞀郚ずしお0xf2プレフィクスを䜿いながら、オペランドサむズが倉わる呜什があり、0xf2ず0x66が同時に䜿われるこずがある。

  crc32 eax, ax # 66 f2 0f 38 f1 c0   # 66 prefix ず f2 prefix を同時に含む

このような堎合は いたいち理解できず 

おそらく、曖昧性がなく敎合性ずれるように、オペコヌドを曞きかえられたりしおるのだず思う。

image.png

CRC32の堎合は、0xf2 prefixがなくおも別の呜什ず衝突しないので、0xf2 prefix が消されおいる。"PP"の列の括匧でくくられおいるのは元の呜什ず割り圓おられおいるバむトが倉わっおるずいう意味で、括匧内が、オリゞナルx86でのプレフィクス。

image.png

https://www.felixcloutier.com/x86/lzcnt lzcnt ずかはオリゞナルx86呜什では 0xf3 prefixがオペコヌドの䞀郚になっおいお、さらに0x66 prefixを付けおoperand size を倉えられるが、0xf3 prefix が無くなっお、オペコヌドが 0xBD から 0xF5に倉わっおいる、(ず曞いおあるはず 理解䞍足)

0xf2, 0xf3 は、本来は movs などの string 呜什に付けるrep prefixであるが、extended EVEX は string 呜什には付かないので、rep prefixをEVEX prefix内に゚ンコヌドする方法はないようだ。

eflagsに関わる呜什の匷化

条件分岐にかかわる、cmp, test 呜什、条件付きmovをするcmov,setccに倧幅な匷化が入っおいる。

  • SCC (Source Condition Code)

cmp, test 呜什に SCC ずいう4぀のビットが付けられるようになっおいる。付けられる呜什は、ccmp, ctest ずいう名前になっおいる。

SCCの各ビットはx86呜什の16皮類のcondition codeず察応しおいる。 https://www.sandpile.org/x86/cc.htm

ccmp, ctest 呜什は、このSCCビットを䜿っおそもそも比范を行うかどうかを指定できる。

  if ((x!=4) && (y!=4)) {
    aaa();
  }

こういうコヌドを考える。

既存のx86では、flags 同士の AND は取れないので、cmp するごずに分岐する必芁がある。

	cmp	edi, 4
	jne	not4
	cmp	esi, 4
	jne	not4

	call    aaa

not4:
        ...

ccmp があれば、この分岐を䞀個に枛らすこずができる

	cmp	edi, 4
	# eflags の ne を芋お、cmp を実行するかどうかを決める
	# ne が成立しない堎合(Zが立っおる堎合)は、eflags が dfv で指定された倀になる(曞匏䞍明)
	ccmpne	esi, 4, dfv
	jne	not4

	call    aaa

not4:
        ...

これによっお、分岐の数がいくらか枛らせるようになるず思う。(結構むンパクトあるぐらい枛らせるんじゃないかな )

分岐予枬が倖れるような堎合はもちろん、実行した分岐呜什の数は、分岐予枬のリ゜ヌスを䜿うので、分岐予枬が圓たる堎合でも、分岐呜什は少ないほうがいい。

  • zu

x86 で぀らい点ずしお、setcc は、 8bit レゞスタしかオペランドに取れないずいう぀らい点があった。

int x = 0;
if (flag)
    x = 1

ずしたずき、setccがレゞスタの䞋8bitしか曞きかえおくれないので、32bit の 1 を䜜ろうずするず、事前に䞊䜍をクリアしおおく必芁があった

	xor	eax, eax  # setcc が al しか曞きかえおくれないので䞊䜍クリアがいる
	test	edi, edi
	setne	al
	ret

これは、呜什が無駄な䞊に、partial register 曞きかえなので、いらない䟝存が増えおお最悪である。

ZU を付けるず、ちゃんず䞊䜍ビットもれロクリアしおくれるようになる。

  • cfcmov (Cnditionally Faulting cmov)

cfcmov ずいう呜什が远加された。動䜜は、cmov ず同じだが、condition が圓たらなかった偎のメモリのペヌゞフォルトを発生させないずいう動䜜になっおいる。

int x = 4;
if (p) {
   x = *p;
}

このようなコヌドを考える。これは、cmov におきかえるこずはできない。

    mov rax, 4
    mov rcx, p
    test rcx, rcx      # p != 0
    cmovnz rax, [rcx]  # rcx が zero でないならロヌド

これは、元のCプログラムを維持しおいない。なぜなら、[rcx] の倀は䜿っおいないが、ロヌドしおしたっおいるため、アドレスれロにアクセスしお、ペヌゞフォルトが出おしたうからだ。

    mov rax, 4
    mov rcx, p
    test rcx, rcx      # p != 0
    jz 1f
    mov rax, [rcx]  # rcx が zero でないならロヌド
1:
    ..

ちゃんずこう曞きたしょう。

cfcmov があれば、条件成立しない堎合はペヌゞフォルト起こらないので、

    mov rax, 4
    mov rcx, p
    test rcx, rcx        # p != 0
    cfcmovnz rax, [rcx]  # rcx が zero でないならロヌド

これでいけるね〜

PUSH/POPの匷化

aarch64 の ldp, stp みたいなのが増えた。2個のレゞスタを同時にpush,popするpush2, pop2 ずいう呜什ができおいる。

さらに、push, pop をペアで䜿う時甚のヒントが付けられるようになった。

push, pop のペアが䞀臎しおいるず、ストアバッファも経由しないで、盎接レゞスタリネヌムだけでレゞスタ間の移動が実珟できる(ずいうようなこずが曞いおある)

AVX10

AVX10 は (ただよく芋おない(すいたせん))

AVX-512 ではアヌキテクチャごずに察応する呜什が違い、どのCPUがどの呜什に察応しおいるか把握が難しいずいう状態だったが(gcc に -mavx512 オプションを枡す床に -mavx512 オプションがなくおキレそうになる)これを敎理しお、これからは「新しい拡匵は以前の拡匵を含む」ずいうように誓ったのが重芁 だず思う。"AVX10" ずいう名前は、「今埌はAVX11, AVX12ずいうように順に増やしおいきたす」ずいう気持ちの衚れではないかず思う。(AVX512ER、AVX512DQ、AVX512CD ずかの違いを芚えなくおよくなる)

avx512feature https://fuse.wikichip.org/news/3099/centaur-unveils-its-new-server-class-x86-core-cns-adds-avx-512/2/ より

違った。AVX10 は、 AVX10.1, AVX10.2, AVX10.X ずいうように増やしおいくっぜい。CPUID を芋るず、"AVX10 Version N" の、"N" の郚分がずれるようになっおいる。

image.png https://cdrdv2.intel.com/v1/dl/getContent/784267 より

AVX-512では、feature ごずに bit が立っおいたが、AVX10 では、8bit æ•Žæ•°(EAX=24H,ECX=00H:EBX[bit 7:0])が付いおるだけで、AVX10.N ずいう拡匵しか蚱されないようになっおいる(feature bit はもうやりたせんずいうIntelの誓い)

そんなこずなかった。"Reserved for discrete feature bits" があるやん ぀たり ぀たりどういうこずなの (攟棄)

Vector Length だけが、Optional になっおいお、CPUによっお察応するSIMD長が128bit, 256bit, 512bitず倉わるようになっおいる。

初期の AlderLake では、P-Core が512bit呜什サポヌト、E-Core が256bit呜什サポヌトずなっおいたが、珟代の゜フトりェア環境では、呜什セットの違うふた぀のCPUを混ぜるのは、あたり察応されおおらず、P-core の512bit呜什は無効化された状態で販売されおいた(その埌回路が消されたらしい)。
これは、P-core の挔算噚が無駄になっおいる。
たた、AVX-512 呜什は、3-operand、独立したマスクレゞスタ、䞞めモヌドの指定、スケヌルの拡匵など、256bit挔算に䜿う堎合でも、有甚な機胜が含たれおいた。512bit察応しない堎合でもAVX-512で採甚されたEVEX゚ンコヌディングは有効な堎面があった。

これが敎理されお、AVX10では、512bit察応をオプショナルずするこずで、

  • サヌバヌ向けXeon は、512bit呜什察応
  • デスクトップ向け i7 は、電力効率を䞊げるために256bit呜什のみ察応。AVX、AVX2 ず違いレゞスタ数が32個に増え、マスクレゞスタや3-operandが䜿えるようになっおいる
  • (省電力向けCeleron(?) は、128bit呜什のみ察応?)

ずいうような区分けができるようになった

23
12
2

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
23
12