Đối với phương pháp thống kê nào là GPU nhanh hơn CPU?


17

Tôi vừa cài đặt card đồ họa Nvidia GT660 trên máy tính để bàn của mình và sau một vài lần vật lộn, tôi đã xoay sở để giao tiếp với R.

Tôi đã chơi với một số gói R sử dụng GPU, đặc biệt là gputools và tôi đang so sánh thời gian sử dụng GPU và CPU của mình để thực hiện một số thao tác cơ bản:

  • đảo ngược ma trận (CPU nhanh hơn)
  • phân tách qr (CPU nhanh hơn)
  • ma trận tương quan lớn (CPU nhanh hơn)
  • nhân ma trận (GPU nhanh hơn nhiều!)

Lưu ý rằng tôi đã thử nghiệm chủ yếu với gputools để có thể các gói khác hoạt động tốt hơn.

Theo nghĩa rộng, câu hỏi của tôi là: những hoạt động thống kê thông thường nào có thể đáng để thực hiện trên GPU hơn là CPU?


1
Bất cứ điều gì liên quan đến nhiều phép nhân ma trận? :) GPU khá phổ biến trong cộng đồng mạng lưới thần kinh.

bạn cần cung cấp kích thước của các ma trận liên quan. Ví dụ: lần kiểm tra cuối cùng tôi đã kiểm tra (thừa nhận 2 năm trước) chỉ đảo ngược và phân tách nhanh hơn trên GPU bắt đầu từ các ma trận lớn (2 ^ 9 lần 2 ^ 9 trở lên)
user189035

1
Tôi đã sử dụng ma trận khoảng cho phép nhân, ma trận và nhân ma trận, trong khi để tương quan, tôi đã sử dụng khoảng 10 ^ 4 quan sát vectơ kích thước 100. Để đảo ngược ma trận, GPU chậm hơn rất nhiều, trong khi để phân tách qr chậm hơn nhưng có thể so sánh với CPU. 103×103
Jugurtha

2
đây là một câu hỏi rất hay nhưng tôi nghĩ bạn sẽ nhận được câu trả lời tốt hơn bằng cách chuyển nó sang stackoverflow (thông qua tôi nghĩ rằng những câu hỏi tương tự đã được hỏi ở đó trước đó)
user189035

2
Ưu điểm của GPU của CPU thông thường là thực tế là chúng có thể "song song" một cách ồ ạt, chứ không phải chúng nhanh hơn trên mỗi lõi. Như vậy, đối với các công việc đòi hỏi nhiều "công việc dọn phòng" như nhân tố Cholesky, v.v., bạn cần sử dụng thuật toán khối và vv để có được tốc độ đáng kể; Điều này không phải là nhỏ và tôi cho rằng sẽ mất một thời gian trước khi GPU tiếp quản các hoạt động như vậy. Những gì chắc chắn sẽ đi theo cách GPU là MCMC-ing (và tạo số ngẫu nhiên). Lấy mẫu từ một hậu thế có "song song" được viết trên đó ... Và các phép tính ma trận thưa thớt; dù sao họ cũng đã bị "chặn" ...
usεr11852 nói rằng Hồi phục Monic

Câu trả lời:


6

GPU là những con thú nhạy cảm. Mặc dù về mặt lý thuyết, thẻ mạnh nhất của Nvidia có thể thực hiện bất kỳ thao tác nào bạn liệt kê nhanh hơn 100 lần so với CPU nhanh nhất, khoảng một triệu thứ có thể cản trở sự tăng tốc đó. Mọi phần của thuật toán có liên quan và của chương trình chạy nó, phải được tinh chỉnh và tối ưu hóa rộng rãi để có thể đạt được bất cứ nơi nào gần tốc độ tối đa lý thuyết đó. R thường không được biết đến là một ngôn ngữ đặc biệt nhanh và do đó, điều đó không làm tôi ngạc nhiên khi việc triển khai GPU mặc định của nó không tốt lắm, ít nhất là về hiệu năng thô. Tuy nhiên, các chức năng GPU R có thể có các cài đặt tối ưu hóa mà bạn có thể điều chỉnh để lấy lại một số hiệu suất bị thiếu đó.

Nếu bạn đang xem xét GPU vì bạn thấy rằng một số tính toán mà bạn cần chạy sẽ mất vài tuần / tháng để hoàn thành, có thể đáng để bạn chuyển từ R sang ngôn ngữ thân thiện với hiệu suất hơn. Python không quá khó để làm việc với R. Các gói NumPy và SciPy có hầu hết các chức năng thống kê giống như R và PyCuda có thể được sử dụng để thực hiện các chức năng dựa trên GPU của bạn theo cách khá đơn giản.

Nếu bạn thực sự muốn tăng tốc độ mà các chức năng của bạn chạy trên GPU, tôi sẽ xem xét thực hiện các chức năng của riêng bạn trong sự kết hợp của C ++ và CUDA. Thư viện CUBLAS có thể được sử dụng để xử lý tất cả các công việc nặng liên quan đến đại số tuyến tính. Tuy nhiên, hãy nhớ rằng việc viết mã như vậy có thể mất nhiều thời gian (đặc biệt nếu đó là lần đầu tiên bạn làm như vậy), và vì vậy cách tiếp cận này chỉ dành riêng cho những tính toán mất nhiều thời gian để chạy (tháng) và / hoặc là bạn sẽ lặp đi lặp lại hàng trăm lần.


6

Theo nghĩa rộng, các thuật toán chạy nhanh hơn trên GPU là những thuật toán mà bạn đang thực hiện cùng một loại hướng dẫn trên nhiều điểm dữ liệu khác nhau.

Một ví dụ dễ dàng để minh họa điều này là với phép nhân ma trận.

Giả sử chúng ta đang thực hiện tính toán ma trận

A×B=C

Một thuật toán CPU đơn giản có thể trông giống như

// bắt đầu bằng 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];
            }
        }
    }
}

Điều quan trọng để thấy ở đây là có rất nhiều vòng lặp lồng nhau và mỗi bước phải được thực hiện lần lượt.

Xem sơ đồ này

Lưu ý rằng việc tính toán từng phần tử của C không phụ thuộc vào bất kỳ phần tử nào khác. Vì vậy, việc tính toán được thực hiện theo thứ tự nào không quan trọng.

Vì vậy, trên GPU, các hoạt động này có thể được thực hiện đồng thời.

Một nhân GPU để tính toán nhân ma trận sẽ trông giống như

__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];
         }
     }
}

Hạt nhân này chỉ có hai vòng lặp bên trong. Một chương trình gửi công việc này tới GPU sẽ yêu cầu GPU thực thi hạt nhân này cho từng điểm dữ liệu trong C. GPU sẽ thực hiện đồng thời từng hướng dẫn này trên nhiều luồng. Giống như câu nói cũ "Cheaper by chục" GPU được thiết kế để nhanh hơn làm điều tương tự nhiều lần.

Tuy nhiên, có một số thuật toán sẽ làm chậm GPU. Một số không phù hợp cho GPU.

Nếu ví dụ, có các phụ thuộc dữ liệu, nghĩa là: hãy tưởng tượng tính toán của từng phần tử của C phụ thuộc vào các phần tử trước đó. Lập trình viên sẽ phải đặt một rào cản trong kernel để chờ cho mỗi tính toán trước đó kết thúc. Đây sẽ là một sự chậm lại lớn.

Ngoài ra, các thuật toán có rất nhiều logic phân nhánh, tức là:

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

có xu hướng chạy chậm hơn trên GPU vì GPU không còn làm điều tương tự trong mỗi luồng.

Đây là một lời giải thích đơn giản vì có nhiều yếu tố khác để xem xét. Ví dụ, gửi dữ liệu giữa CPU và GPU cũng tốn thời gian. Đôi khi nó đáng để thực hiện một tính toán trên GPU ngay cả khi CPU nhanh hơn, chỉ để tránh thời gian gửi thêm (Và ngược lại).

Ngoài ra, nhiều CPU hiện đại hỗ trợ đồng thời cũng như với bộ xử lý đa lõi siêu phân luồng.

GPU dường như cũng không tốt cho đệ quy, xem ở đây có thể giải thích một số vấn đề với thuật toán QR. Tôi tin rằng người ta có một số phụ thuộc dữ liệu đệ quy.


2
Chính thức là SX-nghịch ngợm khi bình luận về một câu trả lời chỉ để nói rằng đó là một câu trả lời tuyệt vời, nhưng tôi không đưa ra ý kiến ​​của một con chuột về phủ định: đây là một câu trả lời thú vị và nhiều thông tin. Một trong những bất công lớn của SX là thiếu tiếng nói đối với những người đưa ra câu trả lời có nhiều thông tin cho các câu hỏi 'cũ' (trong thời gian internet). (Ngoài ra, tôi đang đưa ra một câu trả lời cho câu trả lời 'cũ' (trong thời gian internet): Tôi biết, phải không? META).
GT.

Một xem xét quan trọng là liệu có thực sự có một thư viện để thực hiện tính toán hay không: ví dụ như theo hiểu biết của tôi, không có triển khai GPU dày đặc của phép nhân ma trận, chắc chắn không thông qua các gói R. Nếu bạn chuẩn bị làm việc với việc viết mã GPU C, thì chúc may mắn.
Jack Wasey

4

n=210n,m210,k214

Nhìn rộng hơn, tôi nghi ngờ hầu hết các hoạt động thống kê dành phần lớn thời gian của họ cho đại số tuyến tính dày đặc (BLAS, chức năng Lapack) có thể được triển khai hiệu quả trên GPU.


0

Nhiều phương pháp cho dữ liệu bị thiếu? Giống như những người trong Alice-II (R).

Tôi nghĩ rằng những thứ đó thường có xu hướng song song lúng túng và do đó phù hợp với kiến ​​trúc GPU. Không bao giờ thử bản thân mình mặc dù.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.