Untuk metode statistik manakah GPU lebih cepat dari CPU?

17

Saya baru saja menginstal kartu grafis Nvidia GT660 di desktop saya dan, setelah beberapa perjuangan, saya berhasil menghubungkannya dengan R.

Saya telah bermain dengan beberapa paket R yang menggunakan GPU, terutama gputools, dan saya membandingkan waktu yang dibutuhkan oleh GPU dan CPU saya untuk melakukan beberapa operasi dasar:

  • matriks pembalik (CPU lebih cepat)
  • dekomposisi qr (CPU lebih cepat)
  • matriks korelasi besar (CPU lebih cepat)
  • perkalian matriks (GPU jauh lebih cepat!)

Perhatikan bahwa saya telah bereksperimen terutama dengan gputool jadi mungkin paket lain berkinerja lebih baik.

Secara umum pertanyaan saya adalah: apa beberapa operasi statistik rutin yang mungkin layak dijalankan pada GPU daripada CPU?

Jugurtha
sumber
1
Adakah yang melibatkan banyak perkalian matriks? :) GPU cukup populer di komunitas jaring saraf.
Anda perlu memberikan ukuran matriks yang terlibat. Misalnya, terakhir saya memeriksa (diakui 2 tahun yang lalu) inversi dan dekomposisi hanya lebih cepat pada GPU mulai dari matriks besar (2 ^ 9 kali 2 ^ 9 dan ke atas)
user189035
1
Saya menggunakan matriks sekitar untuk inversi, qr dan perkalian matriks, sedangkan untuk korelasi saya telah menggunakan sekitar 10 ^ 4 pengamatan vektor ukuran 100. Untuk inversi matriks GPU jauh lebih lambat, sedangkan untuk dekomposisi qr itu lebih lambat tapi sebanding dengan CPU. 103×103
Jugurtha
2
ini adalah pertanyaan yang sangat bagus tapi saya pikir Anda akan mendapatkan jawaban yang lebih baik dengan memigrasikannya ke stackoverflow (melalui saya pikir pertanyaan serupa telah diajukan sebelumnya)
user189035
2
Keunggulan GPU dari CPU reguler adalah kenyataan bahwa mereka dapat paralel secara "masif", bukan karena mereka lebih cepat per inti. Dengan demikian, untuk pekerjaan yang membutuhkan banyak "pembersihan" seperti faktorisasi Cholesky dll. Anda perlu menggunakan algoritma blok dan sebagainya untuk mendapatkan kecepatan yang signifikan; ini bukan hal sepele dan saya menganggap itu akan memakan waktu sebelum GPU mengambil alih operasi tersebut. Yang pasti terjadi dengan cara GPU adalah MCMC-ing (dan generasi Random Number). Pengambilan sampel dari posterior memiliki "paralelisasi" yang tertulis di atasnya ... Dan perhitungan matriks yang jarang; mereka sudah "diblokir" ...
usεr11852 mengatakan Reinstate Monic

Jawaban:

6

GPU adalah binatang yang sensitif. Meskipun kartu Nvidia yang paling besar secara teoritis dapat menjalankan operasi apa pun yang Anda daftarkan 100x lebih cepat dari CPU tercepat, sekitar satu juta hal dapat menghalangi kecepatan itu. Setiap bagian dari algoritme yang relevan, dan program yang menjalankannya, harus diubah dan dioptimalkan secara ekstensif agar dapat mendekati kecepatan maksimum teoretis tersebut. R pada umumnya tidak dikenal sebagai bahasa yang sangat cepat, dan karenanya tidak mengejutkan saya bahwa implementasi standar GPU-nya tidak terlalu bagus, setidaknya dalam hal kinerja mentah. Namun, fungsi R GPU mungkin memiliki pengaturan pengoptimalan yang dapat Anda atur untuk mendapatkan kembali sebagian dari kinerja yang hilang itu.

Jika Anda mencari GPU karena Anda menemukan bahwa beberapa perhitungan yang perlu Anda jalankan akan memakan waktu berminggu-minggu / bulan untuk diselesaikan, mungkin ada baiknya Anda bermigrasi dari R ke bahasa yang lebih ramah-kinerja. Python tidak terlalu sulit untuk dikerjakan daripada R. Paket NumPy dan SciPy memiliki sebagian besar fungsi stat yang sama dengan R, dan PyCuda dapat digunakan untuk mengimplementasikan fungsi berbasis GPU Anda sendiri dengan cara yang cukup mudah.

Jika Anda benar - benar ingin meningkatkan kecepatan di mana fungsi Anda berjalan pada GPU, saya akan mempertimbangkan untuk mengimplementasikan fungsi Anda sendiri dalam kombinasi C ++ dan CUDA. Perpustakaan CUBLAS dapat digunakan untuk menangani semua pengangkatan berat terkait aljabar linier. Namun, perlu diingat bahwa perlu waktu cukup lama untuk menulis kode seperti itu (terutama jika ini adalah pertama kalinya Anda melakukannya), sehingga pendekatan ini hanya diperuntukkan bagi perhitungan yang membutuhkan waktu sangat lama untuk dijalankan (berbulan-bulan) dan / atau Anda akan mengulangi ratusan kali.

tel
sumber
6

Secara umum, algoritma yang bekerja lebih cepat pada GPU adalah algoritma di mana Anda melakukan jenis instruksi yang sama pada banyak titik data yang berbeda.

Contoh mudah untuk menggambarkan ini adalah dengan perkalian matriks.

Misalkan kita sedang melakukan perhitungan matriks

SEBUAH×B=C

Algoritme CPU sederhana mungkin terlihat seperti ini

// dimulai dengan C = 0

for (int i = 0; i < C_Width; i++)
{
    for (int j = 0; j < C_Height; j++)
    {
        for (int k = 0; k < A_Width; k++)
        {
            for (int l = 0; l < B_Height; l++)
            {
                C[j, i] += A[j, k] * B[l, i];
            }
        }
    }
}

Kuncinya untuk dilihat di sini adalah ada banyak loop yang bersarang dan setiap langkah harus dijalankan satu demi satu.

Lihat diagram ini

Perhatikan bahwa perhitungan setiap elemen C tidak tergantung pada elemen lainnya. Jadi tidak masalah urutan urut apa yang dilakukan.

Jadi pada GPU, operasi ini bisa dilakukan bersamaan.

Kernel GPU untuk menghitung perkalian matriks akan terlihat seperti ini

__kernel void Multiply
(
    __global float * A,
    __global float * B,
    __global float * C
)
{
     const int x = get_global_id(0);
     const int y = get_global_id(1);
     for (int k = 0; k < A_Width; k++)
     {
         for (int l = 0; l < B_Height; l++)
         {
             C[x, y] += A[x, k] * B[l, y];
         }
     }
}

Kernel ini hanya memiliki dua inner untuk loop. Suatu program yang mengirimkan pekerjaan ini ke GPU akan memberitahu GPU untuk menjalankan kernel ini untuk setiap titik data dalam C. GPU akan melakukan masing-masing instruksi ini secara bersamaan di banyak utas. Sama seperti pepatah lama "Lebih murah oleh selusin" GPU dirancang untuk lebih cepat melakukan hal yang sama berkali-kali.

Namun ada beberapa algoritma yang akan memperlambat GPU. Beberapa tidak cocok untuk GPU.

Jika misalnya, ada dependensi data, yaitu: bayangkan perhitungan setiap elemen C tergantung pada elemen sebelumnya. Programmer harus meletakkan penghalang di kernel untuk menunggu setiap perhitungan sebelumnya selesai. Ini akan menjadi penurunan besar.

Juga, algoritma yang memiliki banyak logika percabangan yaitu:

__kernel Foo()
{
    if (somecondition)
    {
        do something
    }
    else
    {
        do something completely different
    }
}

cenderung berjalan lebih lambat pada GPU karena GPU tidak lagi melakukan hal yang sama di setiap utas.

Ini adalah penjelasan yang disederhanakan karena ada banyak faktor lain yang perlu dipertimbangkan. Misalnya, mengirim data antara CPU dan GPU juga memakan waktu. Kadang-kadang ada baiknya melakukan perhitungan pada GPU bahkan ketika itu lebih cepat pada CPU, hanya untuk menghindari waktu pengiriman tambahan (Dan sebaliknya).

Juga banyak CPU modern mendukung konkurensi sekarang juga dengan prosesor multicore hyperthreaded.

GPU juga tampaknya tidak begitu baik untuk rekursi, lihat di sini yang mungkin menjelaskan beberapa masalah dengan algoritma QR. Saya percaya bahwa seseorang memiliki beberapa dependensi data rekursif.

sa
sumber
2
Sudah resmi SX-nakal untuk mengomentari jawaban hanya untuk mengatakan bahwa itu adalah jawaban yang hebat, tapi saya tidak memberikan perinæum tikus tentang negs: ini adalah jawaban yang menyenangkan dan informatif. Salah satu ketidakadilan SX yang hebat adalah kurangnya pujian kepada orang-orang yang memberikan jawaban yang sangat informatif tentang pertanyaan 'lama' (dalam waktu internet). (Plus, saya memberikan jempol untuk jawaban 'lama' (dalam waktu internet): Saya tahu, kan? META).
GT.
Pertimbangan penting adalah apakah sebenarnya ada perpustakaan untuk melakukan perhitungan: misalnya sepengetahuan saya, tidak ada implementasi GPU multiplikasi matriks multiplikasi yang jarang, tentu saja tidak melalui paket R. Jika Anda siap bekerja dengan menulis kode C GPU, maka semoga berhasil.
Jack Wasey
4

n=210n,m210,k214

Secara lebih luas, saya menduga sebagian besar operasi statistik yang menghabiskan sebagian besar waktu mereka dalam aljabar linier padat (BLAS, fungsionalitas Lapack) dapat diimplementasikan secara efisien pada GPU.

Max Hutchinson
sumber
0

Berbagai metode Imputasi untuk Data yang Hilang? Seperti yang ada di Alice-II (R).

Saya pikir mereka cenderung paralel paralel dan karenanya cocok untuk arsitektur GPU. Namun tidak pernah mencobanya sendiri.

curious_cat
sumber