Для каких статистических методов GPU быстрее, чем CPU?

18

Я только что установил графическую карту Nvidia GT660 на свой рабочий стол, и после некоторой борьбы мне удается связать ее с R.

Я играл с несколькими R-пакетами, использующими графические процессоры, особенно gputools, и сравнивал время, затрачиваемое моим GPU и процессором на выполнение некоторых основных операций:

  • инвертирующие матрицы (процессор быстрее)
  • декомпозиция qr (процессор быстрее)
  • большие корреляционные матрицы (процессор быстрее)
  • умножение матриц (GPU намного быстрее!)

Обратите внимание, что я экспериментировал в основном с gputools, поэтому, возможно, другие пакеты работают лучше.

В общих чертах мой вопрос таков: какие рутинные статистические операции стоит выполнять на GPU, а не на CPU?

Jugurtha
источник
1
Что-нибудь, связанное с большим количеством умножения матриц? :) GPU довольно популярны в сообществе нейронных сетей.
вам нужно указать размер матрицы. Например, последний раз, когда я проверял (по общему признанию 2 года назад), инверсия и декомпозиция были только быстрее на GPU, начиная с больших матриц (2 ^ 9 раз 2 ^ 9 и выше)
user189035
1
Я использовал матрицы около для инверсии, qr и умножения матриц, в то время как для корреляций я использовал около 10 ^ 4 наблюдений векторов размером 100. Для инверсии матриц GPU был намного медленнее, в то время как для разложения qr это было медленнее, но сравнимо с процессором. 103×103
Jugurtha
2
это очень хороший вопрос, но я думаю, что вы получите лучшие ответы, перенеся его в stackoverflow (я думаю, что подобные вопросы уже задавались там ранее)
user189035
2
Преимущество GPU по сравнению с обычными процессорами заключается в том, что они могут быть «массово» параллельными, а не в том, что они быстрее на ядро. Таким образом, для заданий, требующих большого «домашнего хозяйства», таких как факторизация Холецкого и т. Д., Вам необходимо использовать блочные алгоритмы и т. Д., Чтобы получить значительное ускорение; это не тривиально, и я предполагаю, что пройдет некоторое время, прежде чем GPU возьмет на себя такие операции. Что определенно происходит с GPU, так это MCMC-ing (и генерация случайных чисел). Сэмплирование из апостериора имеет "параллелизацию", написанную на всем протяжении ... И разреженные вычисления матриц; они уже "заблокированы" в любом случае ...
говорит ussr11852 Reinstate Monic

Ответы:

6

GPU - чувствительные звери. Хотя beefiest карты Nvidia, теоретически может выполнить любой из операций , перечисленных вами 100x быстрее , чем самый быстрый процессор, около миллионов вещи могут стать на пути этого ускорения. Каждая часть соответствующего алгоритма и программы, которая его запускает, должна быть тщательно настроена и оптимизирована, чтобы приблизиться к этому теоретическому максимальному ускорению. Обычно не известно, что R является особенно быстрым языком, и поэтому меня не удивляет, что его стандартная реализация GPU не так уж хороша, по крайней мере, с точки зрения сырой производительности. Однако функции графического процессора R могут иметь параметры оптимизации, которые можно настроить для восстановления некоторой недостающей производительности.

Если вы смотрите на графические процессоры, потому что обнаружили, что для выполнения некоторых вычислений вам потребуются недели / месяцы, возможно, вам стоит потратить время на переход с R на более удобный язык. С Python работать не намного сложнее, чем с R. Пакеты NumPy и SciPy имеют большинство тех же функций статистики, что и R, и PyCuda можно использовать для реализации ваших собственных функций на основе графического процессора довольно простым способом.

Если вы действительно хотите увеличить скорость, с которой ваши функции выполняются на графических процессорах, я хотел бы рассмотреть возможность реализации ваших собственных функций в комбинации C ++ и CUDA. Библиотека CUBLAS может использоваться для обработки всего, связанного с линейной алгеброй. Однако имейте в виду, что для написания такого кода может потребоваться довольно много времени (особенно, если вы делаете это впервые), и поэтому этот подход должен быть зарезервирован только для тех вычислений, которые выполняются очень долго (месяцы) и / или что вы будете повторять сотни раз.

телефон
источник
6

В общих чертах, алгоритмы, которые работают быстрее на графическом процессоре, - это те, в которых вы выполняете инструкции одного и того же типа для множества различных точек данных.

Простой пример для иллюстрации этого - умножение матриц.

Предположим, что мы делаем матричные вычисления

A×Взнак равноС

Простой алгоритм процессора может выглядеть примерно так

// начиная с 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];
            }
        }
    }
}

Главное, что здесь нужно увидеть, это то, что существует множество вложенных циклов, и каждый шаг должен выполняться один за другим.

Смотрите схему этого

Обратите внимание, что расчет каждого элемента C не зависит от других элементов. Поэтому не имеет значения, в каком порядке производятся расчеты.

Таким образом, на GPU эти операции могут выполняться одновременно.

Ядро GPU для вычисления умножения матриц будет выглядеть примерно так

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

Это ядро ​​имеет только два внутренних цикла for. Программа, отправляющая это задание в GPU, скажет GPU выполнить это ядро ​​для каждой точки данных в C. GPU будет выполнять каждую из этих инструкций одновременно во многих потоках. Точно так же, как старая поговорка «Дешевле на дюжину», графические процессоры предназначены для того, чтобы быстрее делать одно и то же много раз.

Однако есть некоторые алгоритмы, которые замедляют работу графического процессора. Некоторые не очень подходят для графического процессора.

Если, например, были зависимости данных, то есть: представьте, что вычисление каждого элемента C зависело от предыдущих элементов. Программист должен был бы поставить барьер в ядре, чтобы дождаться завершения каждого предыдущего вычисления. Это было бы серьезным замедлением.

Кроме того, алгоритмы, которые имеют много логики ветвления, то есть:

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

на GPU работают медленнее, потому что GPU больше не делает одно и то же в каждом потоке.

Это упрощенное объяснение, потому что есть много других факторов, которые необходимо учитывать. Например, передача данных между процессором и графическим процессором также занимает много времени. Иногда стоит выполнить вычисления на графическом процессоре, даже если он быстрее на процессоре, просто чтобы избежать дополнительного времени отправки (и наоборот).

Кроме того, многие современные процессоры теперь поддерживают параллелизм и с многопоточными многоядерными процессорами.

Также кажется, что графические процессоры не очень хороши для рекурсии, см. Здесь, что, вероятно, объясняет некоторые проблемы с алгоритмом QR. Я считаю, что у кого-то есть рекурсивные зависимости данных.

SAV
источник
2
Официально SX-непослушно комментировать ответ, просто чтобы сказать, что это потрясающий ответ, но я не даю крысам бессмертную оценку о негах: это восхитительный и информативный ответ. Одна из главных несправедливостей SX - это отсутствие признательности людям, которые дают изысканно информативные ответы на «старые» (во времени в Интернете) вопросы. (Плюс, я даю большой палец к «старому» (во времени в Интернете) ответу: я знаю, верно? МЕТА).
GT.
Важное соображение заключается в том, существует ли на самом деле библиотека для вычислений: например, насколько мне известно, нет редких x плотных реализаций GPU для умножения матриц, конечно же, не через пакеты R. Если вы готовы работать с написанием кода на GPU C, тогда удачи.
Джек Уэйси
4

Nзнак равно210N,м210,К214

В более широком смысле, я подозреваю, что большинство статистических операций, которые проводят большую часть своего времени в плотной линейной алгебре (BLAS, функциональность Лапака), могут быть эффективно реализованы на графическом процессоре.

Макс Хатчинсон
источник
0

Несколько методов вменения для отсутствующих данных? Как те, что в Алисе-II (R).

Я думаю, что они часто смущают параллель и, следовательно, подходят для архитектуры GPU. Никогда сам не пробовал.

curious_cat
источник