SIMDによるコードのベクトル化
SSE/AVX命令を使用してデータ並列処理の操作をベクトル化し、コードのパフォーマンスを最適化する技法を学びます。
「SIMDによるコードのベクトル化」はCoddyKit上の無料Assembly Language & x86 Low-Level Systems Programmingレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAssembly Language & x86 Low-Level Systems Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Assembly Language & x86 Low-Level Systems Programmingコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
Intro to Vectorization
Welcome to the final lesson on SIMD! We've learned about SSE/AVX registers and instructions. Now, let's put it all together to vectorize code.
Vectorization is a compiler optimization or manual coding technique that transforms loops to perform operations on multiple data elements simultaneously, rather than one at a time.
Why Vectorize? SIMD Power
Imagine adding two lists of numbers. A traditional (scalar) approach adds one pair at a time. Vectorization, using SIMD, lets you add multiple pairs in a single instruction.
- Scalar:
A[0]+B[0], thenA[1]+B[1], etc. - SIMD:
(A[0], A[1], A[2], A[3]) + (B[0], B[1], B[2], B[3])all at once!
This parallel processing dramatically speeds up repetitive tasks on large datasets.
Data Alignment Matters
For optimal SIMD performance, your data should be aligned in memory. This means the starting address of your data block should be a multiple of the vector size (e.g., 16 bytes for SSE, 32 bytes for AVX).
- Aligned Access: Faster, uses instructions like
MOVAPS. - Unaligned Access: Slower, uses instructions like
MOVUPS, as the CPU needs extra work to fetch data.
Proper alignment helps the CPU fetch data more efficiently, avoiding performance penalties.
Loading Vector Data
To work with data in SIMD registers, you first need to load it from memory. Here are common instructions for single-precision floats (PS):
MOVAPS XMM0, [mem]: Moves 4 aligned single-precision floats from memory toXMM0.MOVUPS XMM0, [mem]: Moves 4 unaligned single-precision floats from memory toXMM0.
Always try to use MOVAPS if your data is guaranteed to be aligned for better performance.
Performing Vector Math
Once data is in SIMD registers, you can perform operations on all elements simultaneously. For example, to add two vectors of single-precision floats:
ADDPS XMM0, XMM1: Adds corresponding packed single-precision floats inXMM1toXMM0. The result is stored inXMM0.
This single instruction performs four separate additions in parallel!
Storing Vector Results
After processing data in SIMD registers, you'll want to store the results back to memory. Similar to loading, there are aligned and unaligned store instructions:
MOVAPS [mem], XMM0: Stores 4 aligned single-precision floats fromXMM0to memory.MOVUPS [mem], XMM0: Stores 4 unaligned single-precision floats fromXMM0to memory.
Again, prioritize MOVAPS for storing if your destination memory is aligned.
Vectorizing an Array Sum
Let's see a simple example of adding two arrays of single-precision floats using SSE instructions. This program adds array1 and array2 and stores the result in result.
We process 4 floats at a time in a loop-like fashion, moving 16 bytes (4 floats) per step.
section .data
; Define 8 single-precision floats (4 bytes each), aligned to 16 bytes
; 'dd' defines a doubleword (4 bytes), suitable for floats
array1: align 16
dd 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0
array2: align 16
dd 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0
result: align 16
dd 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
section .text
global _start
_start:
; Process the first 4 floats (16 bytes)
movaps xmm0, [array1] ; Load 1.0, 2.0, 3.0, 4.0 into xmm0
movaps xmm1, [array2] ; Load 8.0, 7.0, 6.0, 5.0 into xmm1
addps xmm0, xmm1 ; Add packed floats: (9.0, 9.0, 9.0, 9.0)
movaps [result], xmm0 ; Store result to result[0-3]
; Process the next 4 floats (16 bytes offset)
movaps xmm0, [array1 + 16] ; Load 5.0, 6.0, 7.0, 8.0 into xmm0
movaps xmm1, [array2 + 16] ; Load 4.0, 3.0, 2.0, 1.0 into xmm1
addps xmm0, xmm1 ; Add packed floats: (9.0, 9.0, 9.0, 9.0)
movaps [result + 16], xmm0 ; Store result to result[4-7]
; Exit program (Linux specific system call)
mov eax, 1 ; sys_exit system call number
xor ebx, ebx ; exit code 0
int 0x80 ; Call kernelOther Common SIMD Ops
Besides ADDPS, SSE/AVX provide a wide range of instructions for various packed operations:
SUBPS: Subtract packed single-precision floats.MULPS: Multiply packed single-precision floats.DIVPS: Divide packed single-precision floats.ANDPS,ORPS,XORPS: Bitwise logical operations on packed floats.- Comparison instructions (e.g.,
CMPPS): Compare packed floats.
The key is that they all operate on multiple data items simultaneously.
When to Vectorize
Vectorization is a powerful optimization, but it's not always necessary or beneficial. Consider these points:
- Large Datasets: Most effective for loops processing many elements.
- Repetitive Operations: Ideal for identical operations applied to many data items.
- Data Layout: Works best with contiguous, aligned data.
- Overhead: Small loops might incur more overhead from setting up vector registers than the speedup provides.
Compilers can often auto-vectorize, but manual vectorization gives you fine-grained control.
Quick Check: Vectorization
Which of the following are key benefits of vectorizing code using SIMD instructions?
Recap: SIMD Power
Great job! You've now learned how to apply SSE/AVX instructions to vectorize your code.
- Vectorization performs operations on multiple data items simultaneously.
- Proper data alignment is crucial for optimal performance.
- Instructions like
MOVAPS,ADDPS, andMOVAPSare used to load, process, and store packed data. - Vectorization is highly effective for repetitive operations on large, contiguous datasets.
This powerful technique allows you to unlock significant performance gains in your x86 assembly programs. Keep practicing!
AI チューターと学ぶ Assembly — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 12
- レッスン
- 48
よくある質問
「SIMDによるコードのベクトル化」レッスンは無料ですか?
はい。「SIMDによるコードのベクトル化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Assembly Language & x86 Low-Level Systems Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Assembly Language & x86 Low-Level Systems Programmingコースには全4レッスンが含まれています。
「SIMDによるコードのベクトル化」で何を学びますか?
SSE/AVX命令を使用してデータ並列処理の操作をベクトル化し、コードのパフォーマンスを最適化する技法を学びます。 ブラウザで直接実行するハンズオンコードでAssembly Language & x86 Low-Level Systems Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Assembly Language & x86 Low-Level Systems Programmingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAssembly Language & x86 Low-Level Systems Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「SIMDによるコードのベクトル化」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAssembly Language & x86 Low-Level Systems Programmingレッスンでコードを書いて実行できますか?
はい。すべてのAssembly Language & x86 Low-Level Systems Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- x87 FPUプログラミングの基礎
- SSE/AVX命令セット入門
- SIMDによるコードのベクトル化
- 浮動小数点の精度、丸め、例外