Почему MATLAB так быстр в умножении матриц? - PullRequest
175 голосов
/ 19 мая 2011

Я делаю некоторые тесты с CUDA, C ++, C # и Java и использую MATLAB для проверки и генерации матрицы. Но когда я умножаю с MATLAB, 2048x2048 и даже более крупные матрицы почти мгновенно умножаются.

             1024x1024   2048x2048   4096x4096
             ---------   ---------   ---------
CUDA C (ms)      43.11      391.05     3407.99
C++ (ms)       6137.10    64369.29   551390.93
C# (ms)       10509.00   300684.00  2527250.00
Java (ms)      9149.90    92562.28   838357.94
MATLAB (ms)      75.01      423.10     3133.90

Только CUDA конкурентоспособна, но я думал, что по крайней мере C ++ будет несколько ближе и не будет 60x медленнее.

Итак, мой вопрос - как MATLAB делает это так быстро?

C ++ Код:

float temp = 0;
timer.start();
for(int j = 0; j < rozmer; j++)
{
    for (int k = 0; k < rozmer; k++)
    {
        temp = 0;
        for (int m = 0; m < rozmer; m++)
        {
            temp = temp + matice1[j][m] * matice2[m][k];
        }
        matice3[j][k] = temp;
    }
}
timer.stop();

Edit: Я также не знаю, что думать о результатах C #. Алгоритм такой же, как C ++ и Java, но есть гигантский скачок 2048 с 1024?

Edit2: Обновлены MATLAB и 4096x4096 результаты

Ответы [ 12 ]

2 голосов
/ 11 марта 2014

Резкий контраст обусловлен не только удивительной оптимизацией Matlab (как уже говорилось во многих других ответах), но и тем, как вы формулировали матрицу как объект.

Кажется, вы сделали матрицу списком списков?Список списков содержит указатели на списки, которые затем содержат ваши матричные элементы.Местоположения содержащихся списков назначаются произвольно.Поскольку вы перебираете свой первый индекс (номер строки?), Время доступа к памяти очень значительно.Для сравнения, почему бы вам не попробовать реализовать матрицу в виде одного списка / вектора, используя следующий метод?

#include <vector>

struct matrix {
    matrix(int x, int y) : n_row(x), n_col(y), M(x * y) {}
    int n_row;
    int n_col;
    std::vector<double> M;
    double &operator()(int i, int j);
};

И

double &matrix::operator()(int i, int j) {
    return M[n_col * i + j];
}

Тот же алгоритм умножения должен использоваться так, чтобыколичество флопов одинаково.(n ^ 3 для квадратных матриц размера n)

Я прошу вас рассчитать время так, чтобы результат был сопоставим с тем, что вы имели ранее (на той же машине).Сравнение покажет, насколько значительным может быть время доступа к памяти!

2 голосов
/ 20 сентября 2012

Общий ответ на вопрос «Почему Matlab работает быстрее в xxx по сравнению с другими программами» заключается в том, что в Matlab имеется множество встроенных оптимизированных функций.

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

Это можно интерпретировать двумя способами:

1) Обычный / теоретический способ: Matlab не значительно быстрее, вы просто делаете неверный тест

2) Реалистичный способ: для этого материала Matlab быстрее на практике, потому что языки, такие как c ++, слишком легко используются неэффективными способами.

...