Post on 14-May-2020
Paralelisasi Metode Jacobi untuk Komputasi SVD dalam GPU dan
Modifikasinya
Adi Sujiwo
Daftar Isi
1. Pendahuluan β’ Pengantar β’ Executive Summary β’ Penelitian Sebelumnya
2. Tinjauan Pustaka β’ Metode Komputasi SVD β’ Metode Jacobi: Two-Side, Kogbetliantz, One-Side
β’ QR dan SVD β’ General-Purpose GPU
3. Rancangan Algoritma β’ Paralelisasi One-Side Jacobi β’ Paralelisasi QR β’ Prekondisi QR dan SVD Jacobi β’ Analisis Kompleksitas
4. Ujicoba dan Analisis β’ Parameter Pengukuran β’ Hasil dan Pembahasan
β’ Running Time β’ Speed-Up β’ Throughput β’ Bandwidth β’ Validasi
5. Kesimpulan dan Saran
Pendahuluan
Pengantar
β’ Komputasi SVD untuk matriks besar berjalan lambat
β’ Metode klasik untuk SVD: Golub-Kahan-Reisch
β’ Diperlukan cara-cara inovatif untuk mempercepatnya
β’ Paralelisasi SVD dalam GPU
β’ Metode Jacobi terbukti paling mudah diparalelisasi
Executive Summary
β’ Tujuan Penelitian: menyelidiki kemungkinan akselerasi SVD, khususnya metode Jacobi, dengan menggunakan GPU
β’ Penulis membangun: β Rutin SVD dengan metode One-Side Block Jacobi (OSBJA) dalam
GPU β Urutan ortogonalisasi baru: berdasarkan anti-diagonal β Rutin dekomposisi QR dengan metode Rotasi Givens dalam GPU β Kombinasi Jacobi dengan QR dalam GPU
β’ Hasil: β Rutin SVD dengan metode Jacobi dan prekondisi QR mampu
mengungguli Octave pada matriks berukuran besar
Kontribusi
β’ Paralelisasi Jacobian SVD dalam GPU
β’ Metode pengurutan ortogonalisasi per-anti-diagonal matriks pasangan baris
β’ Implementasi QR dengan rotasi Givens dalam GPU
Mengapa GPU ?
β’ Murah-Meriah
β’ Tersedia luas (semua PC pasti memiliki GPU)
β’ Cocok untuk aplikasi data-parallel
β’ Embedded GPU sudah tersedia
Penelitian Sebelumnya
β’ Franklin Luk (1989) : pembuktian konvergensi metode Jacobi
β’ Strumpen et. al. (2003) : implementasi algoritma Jacobi pada prosesor stream
β’ Hari (2005) : modifikasi algoritma Jacobi dengan prekondisi QR
β’ Lahabar et. al. (2008) mengimplementasikan SVD dengan metode Golub-Kahan pada GPU
β’ Shane Ryoo et. al (2008) : prinsip-prinsip optimisasi dan evaluasi aplikasi GPU
Asumsi-Asumsi Dasar
β’ Matriks sumber adalah π β βπΓπ
β’ π β₯ π
β’ Format penyimpanan matriks dalam memori adalah row-major
β’ Presisi tunggal
β’ Indeks array dimulai dari 0
Tinjauan Pustaka
Klasifikasi Algoritma SVD
SVD
Jacobi-Like
Jacobi (2-side)
Hestenes (1-side Jacobi)
Kogbetliantz
QR-Based
Serial QR RRQR Lanczos
Others
Two-Side Jacobi
β’ Dasar: diagonalisasi matriks simetriks melalui perkalian dengan matriks rotasi dari kiri dan kanan
π΄π+1 = π½ π, π, π π΄ππ½ π, π, π π
β’ Update pada baris dan kolom ke-i dan j dapat diparalelkan
β’ Kerugian: harus bekerja dengan baris dan kolom secara bersamaan
Kogbetliantz Method
β’ Dasar: diagonalisasi matriks segitiga π΄ β βπΓπ dengan perkalian dua matriks rotasi berbeda dari kiri dan kanan
π΄π+1 = π½1 π, π, π π΄ππ½2 π, π, π π
β’ Seperti two-side Jacobi, harus bekerja pada baris dan kolom bersamaan
β’ Hari (2007) menyarankan transformasi matriks menjadi bentuk βButterflyβ supaya dapat bekerja dalam baris atau kolom saja.
Metode SVD: One-Side Block Jacobi
β’ Dasar: Rotasi setiap pasang vektor baris sampai saling ortogonal
β’ Memerlukan beberapa kali βsweepβ sampai tercapai ortogonalitas (βkonvergenβ).
β’ Menggunakan rotasi Jacobi untuk membuat dua vektor ortogonal
β’ Mengalikan matriks dengan matriks rotasi dari sisi kiri (βone-sideβ)
β’ Dilakukan per pasangan blok-blok baris berukuran tetap (βblockβ)
Penurunan OSBJA
Iterasi Rotasi
π΄(π‘) = Ξ¦ π‘ Ξ¦ π‘β1 β¦ Ξ¦ 2 Ξ¦ 1 π΄
Sampai didapat baris-baris π΄ π‘ saling ortogonal Rotasi dapat diakumulasi sebagai
ππ = Ξ¦ π‘ Ξ¦ π‘β1 β¦ Ξ¦ 2 Ξ¦ 1 πΌ Sehingga
π΄ π‘ = πππ΄ = Ξ£ππ
Nilai-nilai singular dari A:
π π,π = π΄ π‘ π
ππ π =π΄ π‘ π
π π,π
Matriks rotasiortogonal
Perkalian rotasiortogonal
Output: Matriks ππ β βπΓπ Vektor π β βπ Matriks ππ β βπΓπ
Formula Rotasi
Matriks Rotasi:
Ξ¦ π, π, π =
1β±
π π β±
βπ πβ±
1
Di mana π = cos π dan π = sin π
Menghitung π dan π :
π€ =π΄ π β π΄ π
2(π΄π π β π΄ π )
π‘ =sign(π€)
π€ + 1 + π€2
π =1
1 + π‘2
π = π‘π
Nilai baru baris-baris A setelah rotasi adalah
π΄ π new = ππ΄ π β π π΄ π
π΄ π new = π π΄ π + π π΄ π
Kriteria Konvergensi Jacobi
Strumpen et. al (2003)
πΏ = π π΄ π
π
π
*Dipilih untuk percobaan ini
HPEC Challenge (2006)
πΏ = 10π β max π, π
Urutan Ortogonalisasi
β’ Urutan ortogonalisasi baris mempengaruhi jumlah sweep kecepatan konvergensi
β’ Tiga jenis urutan:
β Serial cyclic-by-row/column
β Paralel (Brent & Luk)
β Odd-Even
β’ Belum ada pembuktian apakah urutan tertentu (selain serial) dijamin konvergen
Brent-Luk Parallel Ordering
β’ Dapat dikerjakan oleh π/2 jumlah prosesor secara serentak
β’ Hasil eksperimen: perlu terlalu banyak sweep jika dibandingkan urutan serial (untuk one-side)
1
2
3
4
5
6
7
8
1
4
2
6
3
8
5
7
1
6
4
8
2
7
3
5
1
8
6
7
4
5
2
3
1
7
8
5
6
3
4
2
1
5
7
3
8
2
6
4
1
3
5
2
7
4
8
6
Langkah 1
Langkah 2
Langkah 3
Langkah 4
Langkah 5
Langkah 6
Langkah 7
Kunggulan dan Kelemahan Metode Jacobi
β’ Keunggulan:
β Sederhana, elegan
β Akurat, mampu menghitung nilai-nilai singular yang kecil
β Potensial diparalelisasi
β’ Kelemahan:
β It is surely SLOW
Prinsip-Prinsip Perbaikan Metode Jacobi (Hari 2005)
β’ Pengurangan jumlah langkah dan sweep
β’ Pengurangan jumlah flop dan waktu CPU dalam satu langkah
β’ Perbaikan detil implementasi: eksploitasi cache, improvisasi dot products, dll.
Modifikasi SVD dengan QR
β’ Prekondisi matriks sumber untuk mengurangi jumlah baris yang harus di-ortogonalisasi
β’ Berguna jika π β« π
β’ Algoritma:
1. Dekomposisi QR: π΄ = π1π
2. Dekomposisi LQ: π = πΏπ2π
3. Hitung SVD: πΏ = π1Ξ£π1π
4. SVD dari A: π΄ = π1π1 Ξ£ π2π1π
Potong R berukuran π Γ π
Perbesar π1 menjadi π Γ π
Metode QR: Rotasi Givens
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
X X X
X X X
X X X
X X X
skip
Input
Metode QR: Rotasi Givens
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
X X X
X X X
X X X
X X X
Metode QR: Rotasi Givens
1 0 0 0
0 1 0 0
v v v v
v v v v
X X X
X X X
X X X
0 X X
Metode QR: Rotasi Givens
1 0 0 0
0 1 0 0
v v v v
v v v v
X X X
X X X
X X X
0 X X
Metode QR: Rotasi Givens
1 0 0 0
v v v v
v v v v
v v v v
X X X
X X X
0 X X
0 X X
Metode QR: Rotasi Givens
1 0 0 0
v v v v
v v v v
v v v v
X X X
X X X
0 X X
0 X X
Metode QR: Rotasi Givens
V V V V
V V V V
V V V V
V V V V
X X X
0 X X
0 X X
0 X X
Metode QR: Rotasi Givens
V V V V
V V V V
V V V V
V V V V
X X X
0 X X
0 X X
0 X X
Metode QR: Rotasi Givens
V V V V
V V V V
C C C C
C C C C
X X X
0 X X
0 X X
0 0 X
Metode QR: Rotasi Givens
V V V V
V V V V
C C C C
C C C C
X X X
0 X X
0 X X
0 0 X
Metode QR: Rotasi Givens
V V V V
C C C C
C C C C
C C C C
X X X
0 X X
0 0 X
0 0 X
Metode QR: Rotasi Givens
V V V V
C C C C
C C C C
C C C C
X X X
0 X X
0 0 X
0 0 X
Metode QR: Rotasi Givens
V V V V
C C C C
Y Y Y Y
Y Y Y Y
X X X
0 X X
0 0 X
0 0 0
Qβ R
Struktur GPU
GPU
Framebuffer / Global Memory
SM 0
SP0 SP1
SP2 SP3
SP4 SP5
SP6 SP7
Memory Controller
Register File
Shared Memory
Cache
SM 1
SP0 SP1
SP2 SP3
SP4 SP5
SP6 SP7
Memory Controller
Register File
Shared Memory
Cache
SM 2
SP0 SP1
SP2 SP3
SP4 SP5
SP6 SP7
Memory Controller
Register File
Shared Memory
Cache
SM 3
SP0 SP1
SP2 SP3
SP4 SP5
SP6 SP7
Memory Controller
Register File
Shared Memory
Cache
Host
SM: Shared MultiprocessorSP: Streaming Processor
PC
I E
xpre
ss B
us
CUDA: Perangkat Pemrograman GPU
β’ Kode konvensional yang berjalan dalam CPU melakukan panggilan kernel yang berjalan pada GPU
β’ Panggilan kernel disertai konfigurasi eksekusi: ukuran grid, block
β’ Kode dalam kernel berjalan per-thread
β’ Thread blockgrid
β’ Sinkronisasi antar thread dalam block (tidak bisa antar block atau global)
β’ Kerjasama antar thread dalam block: sinkronisasi, shared memory, warp.
Hirarki: ThreadBlockGrid
β’ Satu block berjalan pada satu SM
β’ Beberapa block dapat berjalan bersama pada satu SM, dibatasi oleh konsumsi register dan shared memorytetap tidak ada sinkronisasi antar blockbayangkan OS multitasking pada uniprosesor
β’ Grid: kumpulan semua block yang berada dalam GPU
β’ Warp: kelompok 32 thread yang berjalan serentak pada satu block
β’ Divergent warp: percabangan yang membuat anggota warp mengambil jalur kode berbeda
β’ Divergent warp memiliki ongkos yang mahal: setiap cabang harus diselesaikan secara serial
β’ Percabangan antar warp tidak mendapat penalty.
β’ 8 SP untuk menjalankan 32 threadsatu instruksi sederhana perlu minimal 4 clock cycle
block
thread
block
block
block
grid
Pendekatan Pemrograman GPU
β’ Data-Parallelism
β’ Kode CPU sebagai sinkronisasi, GPU sebagai pemrosesan
β’ Implisit: pandang blok sebagai vector processor, gunakan shared memory sebagai penyimpan vektor sesering mungkin
β’ Koordinasikan akses memori dengan sesama thread dalam block
β’ Minimalisir percabangan
Rancangan Algoritma
Paralelisasi OSBJA dalam GPU
β’ Perlu π(π β 1)/2 proses ortogonalisasi per sweep
β’ Urutan kerja: setiap kali proses tidak boleh ada satu baris yang diproses bersamaan
β’ Bagi baris-baris menjadi π kelompok berukuran sama, buat pasangan setiap kelompok dan didapat sebuah matriks pasangan kelompok baris
β’ Tidak semua urutan pengerjaan dijamin konvergen
β’ Solusi: Urutan ortogonalisasi menurut anti-diagonal
β’ Setiap pasangan blok dalam satu anti-diagonal dapat dikerjakan paralel
Urutan Ortogonalisasi Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 0
skip
Dapat dikerjakan paralel
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 1A
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 1A
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 1B
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 1B
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 2A
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 2B
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 3
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 3
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 3
Urutan Pengerjaan Menurut Anti-Diagonal
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
Langkah 3
Implementasi Jacobi dalam CUDA
β’ Kode sinkronisasi antar anti-diagonal dalam CPU
β’ Kode kernel untuk ortogonalisasi sepasang blok barisdipetakan ke satu block GPU
β’ Satu block GPU berisi 64 thread, satu blok baris berisi dua baris
Pembagian Kerja Thread, Block & Grid
0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7
1,1 1,2 1,3 1,4 1,5 1,6 1,7
2,2 2,3 2,4 2,5 2,6 2,7
3,3 3,4 3,5 3,6 3,7
4,4 4,5 4,6 4,7
5,5 5,6 5,7
6,6 6,7
7,7
grid
block
Kernel Jacobi
for (i=0: π/π β 1) { row1 [tid] = A [π1*n + i*b + tid]; row2 [tid] = A [π2*n + i*b + tid]; row3 [tid] = row1 [tid] * row2 [tid]; row2 [tid] = row2 [tid] * row2 [tid]; row1 [tid] = row1 [tid] * row1 [tid]; __syncthreads (); if (tid < 32) { row1 [tid] += row1 [tid + 32]; row1 [tid] += row1 [tid + 16]; row1 [tid] += row1 [tid + 8]; row1 [tid] += row1 [tid + 4]; row1 [tid] += row1 [tid + 2]; row1 [tid] += row1 [tid + 1]; row3 [tid] += row3 [tid + 32]; row3 [tid] += row3 [tid + 16]; row3 [tid] += row3 [tid + 8]; row3 [tid] += row3 [tid + 4]; row3 [tid] += row3 [tid + 2]; row3 [tid] += row3 [tid + 1]; } else { row2 [tid] += row2 [tid + 32]; row2 [tid] += row2 [tid + 16]; row2 [tid] += row2 [tid + 8]; row2 [tid] += row2 [tid + 4]; row2 [tid] += row2 [tid + 2]; row2 [tid] += row2 [tid + 1]; } if (tid==0) { row1 [b] += row1 [0]; row2 [b] += row2 [0]; row3 [b] += row3 [0]; } }
Tahap 1: Menghitung dot products
β’ π1 = π₯1 β π₯1
β’ π2 = π₯2 β π₯2
β’ π3 = π₯1 β π₯2
βLoop Unrollβ Syarat jumlah baris harus kelipatan π = 64
Akumulasi dot products
Menunggu semua thread selesai memuat vektor ke dalam shared memory
Kernel Jacobi
if (tid==0) { swap = (π1 < π2); if (swap) { S [π1] = π2; S [π2] = π1; } else { S [π1] = π1; S [π2] = π2; } if ( π > πΏ) converged = false; if ( π > ν) {
π€ =π2βπ1
2π3
π‘ =sign(π€)
π€ + 1+π€2
π =1
1+π‘2
π = ππ‘
} else { c = 1; s = 0; } } __syncthreads ();
Tahap 2: Menghitung Rotasi (cos π dan sin π)
Proses ini hanya dikerjakan oleh thread pertama dan disimpan pada shared memory untuk mengurangi penggunaan register yang berdampak berkurangnya utilisasi prosesor.
Penggunaan satu thread untuk kode serial seperti ini membuat kernel lebih efisien: 5~6% lebih cepat daripada semua thread ikut menghitung
Implicit bubble sort row pivoting
Kernel Jacobi
for (i=0: π/π β 1) { π1 = row1 [tid] = A [π1*n + i*b + tid]; π2 = row2 [tid] = A [π2*n + i*b + tid]; row1 [tid] = c*π1 β s*π2; row2 [tid] = s*π1 + c*π2; if (swap) { A [π2*n + i*b + tid] = row1 [tid]; A [π1*n + i*b + tid] = row2 [tid]; } else { A [π1*n + i*b + tid] = row1 [tid]; A [π2*n + i*b + tid] = row2 [tid]; } } for (i=0: π/π β 1) { π1 = row1 [tid] = U [π1*n + i*b + tid]; π2 = row2 [tid] = U [π2*n + i*b + tid]; row1 [tid] = c*π1 β s*π2; row2 [tid] = s*π1 + c*π2; if (swap) { U [π2*m + i*b + tid] = row1 [tid]; U [π1*m + i*b + tid] = row2 [tid]; } else { U [π1*m + i*b + tid] = row1 [tid]; U [π2*m + i*b + tid] = row2 [tid]; } }
Tahap 3: Menerapkan rotasi pada matriks π΄ dan π.
Memuat vektor dalam kelipatan π
Dikerjakan dalam shared memory
Paralelisasi Givens-QR dalam GPU
X X X
X X X
X X X
X X X
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
skip
A
Paralelisasi Givens-QR dalam GPU
X X X
0 X X
X X X
0 X X
X X X X
X X X X
X X X X
X X X X
blok #0
blok #1
Paralelisasi Givens-QR dalam GPU
X X X
0 X X
0 X X
0 X X
X X X X
X X X X
X X X X
X X X X
blok #0
Paralelisasi Givens-QR dalam GPU
X X X
0 X X
0 0 X
0 X X
X X X X
X X X X
X X X X
X X X X
blok #0
Percabangan dalam GPU mahal, jadi seluruh baris
diproses
Paralelisasi Givens-QR dalam GPU
X X X
0 X X
0 0 X
0 0 X
X X X X
X X X X
X X X X
X X X X
blok #0
Paralelisasi Givens-QR dalam GPU
X X X
0 X X
0 0 X
0 0 0
X X X X
X X X X
X X X X
X X X X
blok #0
Paralelisasi Givens-QR dalam GPU
X X X
0 X X
0 0 X
0 0 0
X X X X
X X X X
X X X X
X X X X
R
Qβ
SVD Jacobi dengan Prekondisi QR
QR2
1. Dekomposisi QR: π΄ = π1π
2. Dekomposisi LQ pada R:
1. Transpose π β βπΓπ
2. QR pada π π: π π = π2πΏπ
3. Transpose π2, πΏπ
3. Jacobi SVD pada πΏ: πΏ = π1Ξ£π1
π
4. Bangun ππ: ππ = π1ππ2
π
5. Bangun π : π = π1π1
QR1
1. Dekomposisi QR: π΄ = π1π
2. Jacobi SVD pada π : π = π1Ξ£ππ
3. Bangun π: π = π1π1
Analisis Kompleksitas β’ Jacobi
β Memory: π = π2 + ππ + π2 + π
β Workload: π β π 6π3 + 12π2π + ππ + π2
β Transfer: π β 2π 2π3 + 3π2π + ππ + 2π2
β’ Dekomposisi QR β Memory: π = ππ + π2
β Workload: π β 6π2π + 3ππ2 β 3π3
β Transfer: π β 4π2π + 2π2π + 2π2 β 2π2
β’ QR2 β Memory: π = 2π2 + ππ + 4π2 + π
β Workload: π β 6π2π + 5ππ2 + π3 18π + 11 β 4π2
β Transfer: π β 4π2π + 4ππ2 + π3 5π + 8 + 2π2 +9π2
β’ QR1 β Memory: π = 2π2 + ππ + 2π2 + π
β Workload: π β 6π2π + 5ππ2 + 18ππ3 β π2
β Transfer: π β 4π2π + 4ππ2 + 5ππ3 + 2π2 + π2
Workload: jumlah FLOP selama rutin berjalan dalam GPU
Transfer: Jumlah transfer input dan output antara chip dan memori GPU
QR2 dan QR1 tampak tidak sensitif pada perbedaan jumlah kolom/baris.
Ujicoba dan Analisis
Pengujian Program
Percobaan: mencatat running time keempat program dan rutin SVD dari Octave
β’ Parameter
β Running time
β Throughput
β Bandwidth
β Speed-Up
β’ Tipe matriks input
β Random
β Hilbert
β Image
Perangkat Pengujian
β’ Yang dibangun: β QR2 β QR1 β GPU Jacobi β CPU Jacobi
β’ Software β Cuda Toolkit 3.2 β GCC 4.4+Linux 64 bit β Octave single CPU, gold standard
β’ Hardware β GPU: GeForce 9500 GT, RAM DDR2 512 MB β CPU: Core 2 Duo E7200, RAM DDR2 2GB
Pengujian Validitas
β’ Setiap babak mencakup pengujian hasil SVD
β’ Persyaratan validitas
β max π π π β πΌ β€ π π ortogonal
β max π π π β πΌ β€ π π ortogonal
β max π π π π β π΄ β€ πΏ
Di mana πΏ β 10π β min π, π (HPEC Challenge 2006).
Pencatatan Waktu
β’ GPU Timer dari manajemen event CUDA
β’ Fungsi clock_gettime(2) untuk rutin CPU
β’ Tic-Toc (Octave)
Running Time (1)
0
500
1000
1500
2000
2500
3000
0 500 1000 1500 2000 2500 3000 3500 4000
Wak
tu
QR2 QR1 Jacobi CJacobi Octave
Matriks: random, Variasi: jumlah kolom, Baris: 4096
Running Time (2)
0
10
20
30
40
50
60
0 500 1000 1500 2000 2500 3000 3500 4000
Wak
tu
QR2 QR1 Jacobi CJacobi Octave
Matriks: random, Variasi: jumlah baris, Kolom: 64
Running Time (3)
0
500
1000
1500
2000
2500
3000
0 500 1000 1500 2000 2500 3000 3500 4000
Wak
tu
QR2 QR1 Jacobi CJacobi Octave
Matriks: random, Variasi: square
Hasil Pengujian (4)
0
500
1000
1500
2000
2500
0 500 1000 1500 2000 2500 3000 3500 4000
Wak
tu
QR2 QR1 Jacobi CJacobi Octave
Matriks: hilbert, Variasi: jumlah kolom, Baris: 4096
Running Time (5) Matriks: sparse, Variasi: jumlah baris, Kolom: 64
0
5
10
15
20
25
30
35
40
45
50
0 500 1000 1500 2000 2500 3000 3500 4000
Wak
tu
QR2 QR1 Jacobi CJacobi Octave
Running Time (6)
0
500
1000
1500
2000
2500
0 500 1000 1500 2000 2500 3000 3500 4000
Wak
tu
QR2 QR1 Jacobi CJacobi Octave
Matriks: hilbert, Variasi: square
Running Time (7)
0 200 400 600 800 1000 1200 1400 1600 1800 2000
QR2
QR1
Jacobi
CPU Jacobi
Octave
Waktu (detik)
Matriks: Image 1, Ukuran: 4096 Γ 3072
Running Time (8)
0 500 1000 1500 2000 2500 3000 3500
QR2
QR1
Jacobi
CPU Jacobi
Octave
Waktu (detik)
Matriks: Image 2, Ukuran: 4096 Γ 3072
Pembahasan: Running Time
β’ Waktu komputasi sangat bergantung pada kondisi matriks sumber
β’ Kode GPU Jacobi secara umum lebih cepat daripada kode CPU
β’ Jacobi+QR pada matriks persegi lebih cepat dari Jacobi murni pada GPU dan sebaliknya pada matriks square
β’ Kode GPU lebih lambat untuk matriks kecil (β€ 512 Γ 512) karena overhead komunikasi CPUGPU
β’ Seperti diprediksi, rutin Jacobi murni sangat berpengaruh terhadap jumlah sweep
β’ Bagaimana memprediksi jumlah sweep ?
β’ Octave mendapat kesulitan ketika mendapat banyak vektor tidak independen (gambar 2)
Jumlah Sweep (Matriks Random)
Ukuran Metode
GPU Jacobi CPU Jacobi QR2 QR1
64 Γ 64 8 8 8 8
256 Γ 64 9 9 7 7
2048 Γ 2048 10 10 9 10
4096 Γ 2048 11 10 10 10
4096 Γ 3072 10 10 10 9
4096 Γ 4096 10 10 10 10
Jumlah Sweep (Matriks Hilbert)
Ukuran Metode
GPU Jacobi CPU Jacobi QR2 QR1
64 Γ 64 6 6 6 6
256 Γ 64 7 7 7 7
2048 Γ 2048 9 9 8 8
4096 Γ 2048 9 9 8 8
4096 Γ 3072 9 9 8 8
4096 Γ 4096 9 9 8 8
Speed-Up (1)
0
50
100
150
200
250
300
0 500 1000 1500 2000 2500 3000 3500 4000
Kolom
QR2 QR1 Jacobi
Speed-Up (2)
0
50
100
150
200
250
300
0 500 1000 1500 2000 2500 3000 3500 4000
Jumlah Baris
QR2 QR1 Jacobi
Speed-Up (3)
0
0,2
0,4
0,6
0,8
1
1,2
1,4
0 500 1000 1500 2000 2500 3000 3500 4000
Square
QR2 QR1 Jacobi
Pembahasan: Speed-Up
β’ Kode GPU memiliki speed-up rendah untuk jumlah baris kecil (π β€ 256)overhead sinkronisasi CPU-GPU sangat besar
β’ Pada matriks square berukuran besar, kode Jacobi pada GPU tidak unggul signifikan
Throughput (1)
0
10
20
30
40
50
60
70
0 500 1000 1500 2000 2500 3000 3500 4000
Gfl
op
/s
Jumlah Kolom
QR2
QR1
Jacobi
Throughput (2)
0
10
20
30
40
50
60
70
0 500 1000 1500 2000 2500 3000 3500 4000
Gfl
op
s/s
Jumlah Baris
QR2
QR1
Jacobi
Throughput (3)
0
1
2
3
4
5
6
7
8
9
0 500 1000 1500 2000 2500 3000 3500 4000
Gfl
op
s/s
Ukuran
QR2
QR1
Jacobi
Pembahasan: Throughput
β’ Perbedaan karakteristik dalam throughput QR2 dan QR1 tidak signifikan, namun QR2 membutuhkan memori lebih besar
β’ Ketiga algoritma ini masih berada di bawah batas throughput GPU (134 Gflop/s)
β’ Perlu optimalisasi kode floating point dan pola akses memori
Bandwidth (1)
0,00
20,00
40,00
60,00
80,00
100,00
120,00
140,00
160,00
180,00
0 500 1000 1500 2000 2500 3000 3500 4000
Ban
dw
idth
(G
B/s
)
Kolom
QR2
QR1
Jacobi
Bandwidth (2)
0,00
20,00
40,00
60,00
80,00
100,00
120,00
140,00
160,00
180,00
0 500 1000 1500 2000 2500 3000 3500 4000
GB
/s
Baris
QR2
QR1
Jacobi
Bandwidth (3)
0,00
2,00
4,00
6,00
8,00
10,00
12,00
0 500 1000 1500 2000 2500 3000 3500 4000
GB
/s
Ukuran
QR2
QR1
Jacobi
Pembahasan (Bandwidth)
β’ Anomali pada Jacobi berukuran βkurusβ: bandwidth maksimal GPU adalah 32 GB/s.
β’ Dugaan: efek cache memory dalam prosesor namun transparan dari software
β’ Perlu perubahan kode untuk eksploitasi cache
β’ Perlu perubahan kode untuk memperbaiki pola akses memori
Hasil Validasi
β’ Metode Jacobi dapat menghitung SVD secara akurat, sesuai dengan akurasi mesin (presisi tunggal)
β’ Pengecualian: kasus rank-deficient (contoh: gambar 2)
β’ Nilai-nilai singular berhasil dihitung, namun matriks π dan/atau ππ mengandung NaN
Kesimpulan dan Saran
Kesimpulan
β’ Metode Jacobi SVD dalam GPU dapat mengungguli metode sebelumnya yang berbasis bidiagonalisasi, terutama pada matriks berukuran besar
β’ Penggunaan urutan ortogonalisasi paralel menurut anti-diagonal mampu mencapai konvergensi
β’ Perlakuan prekondisi dengan QR mampu mengurangi waktu untuk metode Jacobi pada keadaan m β« π
β’ Metode Jacobi belum mampu menangani kasus rank-deficient
Saran
Masih terdapat ruang untuk perbaikan metode Jacobi dalam GPU:
β’ Eksploitasi bentuk matriks segitiga hasil prekondisi dengan QR/LQ: metode Kogbetliantz
β’ Penanganan kasus rank-deficient
β’ Penanganan kasus π β€ π. Dapat dilakukan dengan lebih dulu transpose matriks in-place.
Terima Kasih