文字、文字列を探すにはCLI命令とCLC命令、複数文字の中から何れかの文字を探すにはTRT命令が利用できます。z/Architectureの今日では、これらのよく知られた命令に加え、SRST命令やTRTE命令、更にはベクトル命令も利用できます。
単一文字の探索
SRST命令による単一文字の探索
1 2 3 4 5 6 7 8 9 10 |
LHI R3,AREALNG LOAD TEXT AREA LENGTH L R4,=A(TEXTAREA) LOAD TEXT AREA ADDRESS LA R0,C'Z' GR0 <--- CHARACTER TO SEARCH LOOP DS 0H SRST R3,R4 SEARCH CHARACTER + CC=0: N/A BC 4,FOUND CC=1: CHARACTER IS FOUND BC 2,NOTFOUND CC=2: CHARACTER IS NOT FOUND BC 1,LOOP CC=3: Paused by CPU decision : |
CLIのように1バイトずつアドレスをずらしながらループする必要はありません。31ビット・アドレッシング・モードでは領域の最大長は2GBです。領域が余りに長いとCPU判断で命令動作は途中で停止します。この時はCC=3が通知されるので、単純に命令を再実行すれば続きから再探索されます。
ベクトル命令による単一文字の探索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
LHI R0,1024/16 SET LOOP COUNTER LA R3,CHARAREA GR3 ---> NEXT TEXT DATA ADDRESS VZERO VR17 CLEAR VR17 VREPIB VR19,C'Z' LOAD C'Z' INTO VR19'S ALL BYTES SEARCH_VCEQB DS 0H VL VR16,0(,R3) LOAD NEXT 16BYTE DATA INTO VR16 VCEQB VR16,VR16,VR19 COMPARE VR16 AND VR19 VLCB VR16,VR16 LOAD EACH BYTE'S COMPLEMENT VAB VR17,VR17,VR16 ADD VR16'S EACH BYTE INTO VR17 LA R3,16(,R3) LOCATE TO NEXT TEXT DATA ADDR BCT R0,SEARCH_VCEQB LOOP FOR REMAINING DATA VZERO VR0 CLEAR VR0 VSUMB VR17,VR17,VR0 SUM EACH BYTES IN SAME WORD IN VR17 VSUMQF VR17,VR17,VR0 SUM EACH WORDS IN VR17 VLGVG R1,VR17,1 LOAD IT INTO GR1(NUM OF CHARS) : |
ベクトル命令(SIMD命令)による単一文字の探索例です。1度に16バイト分の領域を同じ文字で比較します。命令の組み合わせ方はとても複雑ですが、単純なCLI命令でのループに比べれば繰り返し数は1/16にできます。SRST命令もかなり効率的ですがそれ以上です。COBOLコンパイラーも最新機種に合わせて文字列処理にベクトル命令を使うような最適化がなされています。
文字列の探索
SRST命令による文字列の探索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
LHI R3,AREALNG LOAD TEXT AREA LENGTH LARL R4,TEXTAREA LOAD TEXT AREA ADDRESS LA R0,C'A' GR0 <--- CHARACTER TO SEARCH LOOP DS 0H SRST R3,R4 SEARCH CHARACTER + CC=0: N/A BC 4,TSTFOUND CC=1: CHARACTER IS FOUND BC 2,NOTFOUND CC=2: CHARACTER IS NOT FOUND BC 1,LOOP CC=3: Paused by CPU decision TSTFOUND DS 0H CLC 0(L'STRING,R3),STRING IS HERE THE TARGET STRING ? BE FOUND LA R4,1(,R3) CORRECT RESUME ADDRESS LARL R3,TEXTAREA LOAD TEXT AREA ADDRESS AHI R3,AREALNG LOCATE TO END OF AREA SLR R3,R4 LOAD REMAINING LENGTH B LOOP SEARCH AGAIN : |
SRST命令はSEARCH STRINGですが、実際には1文字の探索です。文字列を探索する場合は、先頭文字で探して見つかったら文字列全体をCLCで比較します。2文字目以降が異なっていたら、探索再開アドレスと残りの領域長をレジスターに設定し直して元のループに戻ります。CLC命令をループさせるより遙かに効率よく探し出せます。
ベクトル命令による文字列の探索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
L R14,=A(TEXTAREA) GR14 <-- NEXT DATA AREA LA R1,1024 LA R1,0(R1,R14) GR1 <--- END OF DATA AREA LA R0,L'STRING LOAD STRING LENGTH SLR R1,R0 AVOID EXCEEDING THE END OF STORAGE L R15,=A(STRING) VLL VR22,R0,0(R15) VR22 <-- STRING CHARACTERS VLVGF VR23,R0,1 VR23 <-- GR0(STRING LENGTH) SEARCH_VSTRS DS 0H VL VR21,0(,R14) VR21 <-- NEXT REMAINING DATA VSTRS VR20,VR21,VR22,VR23,0 SEARCH STRING IN VR21 VLGVF R0,VR20,1 EXTRACT FOUND OFFSET IN VR21 BC 2,FOUND CC=2, A FULL MATCH WAS FOUND. BXLE R14,R0,SEARCH_VSTRS LOOP UNTIL END OF DATA AREA B NOTFOUND FOUND DS 0H ALR R14,R0 GR14 --> STRING ADDRESS NOTFOUND DS 0H : |
IBM z15以降でサポートされたベクトル拡張機能2で実装されたVSTRS命令による文字列の探索例です。文字列探索の場合も、比較文字列と被比較領域内容をベクトル・レジスターに読み込んで処理が行われます。そのため、探索できる文字列長は最大で16バイトです。16バイトを超える文字列の場合は、先頭の16バイト分をベクトル命令で探索して、一致箇所が見つかったら残りのデータをCLC命令等で比較します。数百バイトを超えるような領域の探索や内容を変えての探索処理を繰り返し行うような場合は、領域の先頭からCLC命令を1バイトずつアドレスをずらしながら実行するよりも効率良く探索できます。
命令の違いによる実行速度の比較
命令 | 処理速度(CPU時間:単位=秒) |
---|---|
CLI | 0.000814 |
SRST | 0.000082 |
VCEQB | 0.000044 |
命令 | 処理速度(CPU時間:単位=秒) |
---|---|
CLC | 0.001885 |
SRST+CLC | 0.000267 |
VSTRS | 0.000233 |
命令 | 処理速度(CPU時間:単位=秒) |
---|---|
SRST+CLC | 0.000154 |
VSTRS | 0.000233 |
複数の単一文字の探索
TRTE命令による256バイトを超える領域の探索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
MVI SCANTAB+C'A',4 BUILD FUNCTION BYTE TABLE MVI SCANTAB+C'K',8 I MVI SCANTAB+C'0',12 V LARL R4,TEXTAREA LOAD TEXT AREA ADDRESS LLILF R5,AREALNG LOAD TEXT AREA LENGTH LA R1,SCANTAB GR1 ---> FUNCTION BYTE TABLE TRTELOOP DS 0H TRTE R4,R15,0 FIND CHARACTERS + (op1: FOUND ADDRESS) + (op1+1: REMAINING LENGTH) + (op2: FOUND FUNC_BYTE) BC 1,TRTELOOP CC=3: Paused by CPU decision BC 8,TRTEDONE CC=0: NOT FOUND CHARACTER + CC=1: FOUND ANY CHARACTER B *+4(R15) BRANCH BY FOUND CHARACTER NOP 0 00: N/A B FOUND_A 04: FOUND CHAR = C'A' B FOUND_K 08: FOUND CHAR = C'K' B FOUND_0 12: FOUND CHAR = C'0' TRTENEXT DS 0H LA R4,1(,R4) LOCATE TO NEXT BYTE BCTR R5,0 ADJUST REMAINING LENGTH B TRTELOOP BACK TO LOOP FOUND_A DS 0H : B TRTENEXT TRTEDONE DS 0H : SCANTAB DC XL256'00' FUNCTION BYTE TABLE |
256バイトを超える領域の探索表による探索を1回で行えます。TRT命令では256バイトを超える領域であれば256バイトずつ分割して実行することになりますが、TRTE命令を使えば31ビット・アドレッシング・モードでは領域の最大長は2GBです。TRTE命令もSRST命令同様に領域が余りに長いと命令動作は途中で停止します(CC=3)。TRTE命令は長い領域を探索するだけでなく、引数と機能バイトを2バイトにすることもできます。