Как Matlab может быть полезен программисту - страница 4

 

Сразу несколько слов о своей машине:

2024.12.09 01:05:13.335 Terminal        Windows 11 build 22621, 3 x AMD Phenom II X3 720, x64, 13 / 15 Gb memory, 268 / 930 Gb disk, UAC, GMT+3

Name of architecture: X64 Regular
Compiler build number: 4731


Взял пример из Документации Матлаба. Слегка его перекроил, получилось вот что:

%% 1) Create two random matrices
tic
A_MX = rand(12000,4400);
B_MX = rand(12000,4400);
toc
%% 2) Hadamard product
tic
C_MX1 = A_MX.*B_MX;
toc
%% 3) Matrix product
tic
A_MX2 = A_MX';
C_MX2 = A_MX2*B_MX;
toc

где tic\toc - это функции для замера времени выполнения.

Результаты такие:

  1. Elapsed time is 1.858269 seconds.
  2. Elapsed time is 0.257687 seconds.
  3. Elapsed time is 18.325017 seconds.


Аналогичный скрипт для МТ5:

#define ROWS 12000
#define COLS 4400
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
   {
   ::PrintFormat("Name of architecture: %s", __CPU_ARCHITECTURE__);
   ::PrintFormat("Compiler build number: %d", __MQL5BUILD__);   
   //---
   ulong tic = ::GetTickCount64();
   // 1) Create two random matrices
   matrix A_MX, B_MX;
   if(!A_MX.Resize(ROWS, COLS))
      return;
   A_MX.Random(0., 1.);
   if(!B_MX.Resize(ROWS, COLS))
      return;
   B_MX.Random(0., 1.);
   ulong toc = ::GetTickCount64() - tic;
   ::PrintFormat("Elapsed: %0.6f seconds", toc / 1000.);
   // 2) Hadamard product
   tic = ::GetTickCount64();
   matrix C_MX1 = A_MX * B_MX;
   toc = ::GetTickCount64() - tic;
   ::PrintFormat("Elapsed: %0.6f seconds", toc / 1000.);
   // 3) Matrix product
   tic = ::GetTickCount64();
   matrix A_MX2 = A_MX.Transpose();
   matrix C_MX2 = A_MX2.MatMul(B_MX);
   toc = ::GetTickCount64() - tic;
   ::PrintFormat("Elapsed: %0.6f seconds", toc / 1000.);
   //C_MX2.GeMM(A_MX2, B_MX, 1, 0);
   }
//+------------------------------------------------------------------+


И вот такие результаты:

  1. Elapsed: 0.750000 seconds
  2. Elapsed: 0.375000 seconds
  3. Elapsed: 219.969000 seconds
Тут "порадовало" матричное умножение... нужно будет попробовать matrix::GeMM().
 

Попробовал  matrix::GeMM(). Вообще огонь - "привёз" 449.141 сек. Может памяти и меньше тратит, но скорость падает...

Пока что первичный вывод такой - Матлаб будет пошустрее с большими матрицами. Было бы интересно узнать результаты коллег, особенно в МТ5.

 
Denis Kirichenko #:

Попробовал  matrix::GeMM(). Вообще огонь - "привёз" 449.141 сек. Может памяти и меньше тратит, но скорость падает...

Пока что первичный вывод такой - Матлаб будет пошустрее с большими матрицами. Было бы интересно узнать результаты коллег, особенно в МТ5.

Проблема в "AMD Phenom II X3 720" - надо менять, если речь идет об серьезных вычислениях. Это процессор 2010 года без AVX.

По факту мы не используем специализированные расчетные кернелы для старых процессоров и для них гоняем наивные/лобовые алгоритмы.


Вот мои результаты на 32 x AMD Ryzen 9 9950X 16-Core, AVX2:

2024.12.09 01:17:38.155 test (EURUSD,H1)        Name of architecture: X64 Regular
2024.12.09 01:17:38.155 test (EURUSD,H1)        Compiler build number: 4731
2024.12.09 01:17:38.359 test (EURUSD,H1)        Elapsed: 0.204000 seconds
2024.12.09 01:17:38.407 test (EURUSD,H1)        Elapsed: 0.046000 seconds
2024.12.09 01:17:47.891 test (EURUSD,H1)        Elapsed: 9.485000 seconds              <- matrix C_MX2 = A_MX2.MatMul(B_MX);


2024.12.09 01:19:46.497 test (EURUSD,H1)        Name of architecture: X64 Regular
2024.12.09 01:19:46.497 test (EURUSD,H1)        Compiler build number: 4731
2024.12.09 01:19:46.696 test (EURUSD,H1)        Elapsed: 0.188000 seconds
2024.12.09 01:19:46.744 test (EURUSD,H1)        Elapsed: 0.047000 seconds
2024.12.09 01:19:47.766 test (EURUSD,H1)        Elapsed: 1.015000 seconds             <- matrix C_MX2; C_MX2.GeMM(A_MX2, B_MX, 1, 0);

Наиболее оптимизированные операции в OpenBLAS, базовые операции мы тоже постепенно оптимизируем под максимальную производительность.


Прогнал на том же компьютере в Mathlab R2024B:

>> %% 1) Create two random matrices
tic
A_MX = rand(12000,4400);
B_MX = rand(12000,4400);
toc
%% 2) Hadamard product
tic
C_MX1 = A_MX.*B_MX;
toc
%% 3) Matrix product
tic
A_MX2 = A_MX';
C_MX2 = A_MX2*B_MX;
toc
Elapsed time is 0.392029 seconds.
Elapsed time is 0.035336 seconds.
Elapsed time is 1.156901 seconds.
>> 
Наш GeMM даже быстрее оказался, 1.01 sec против 1.15 sec
 
Ренат, спасибо большое за наводку. Буду обновляться ))
Ещё интересно посмотреть, как быстро эти расчёты пройдут в OpenCL.
 

Важно, что фактически не имеет смысла заниматься бенчмарками на терминалах/процессорах без пометки хотя бы AVX.

Версия терминала в режиме Regular x64 собрана в режиме максимальной совместимости и с минимальными оптимизациями. Для процессоров без AVX вне зависимости от количества ядер или частоты процессора используются математические функции без мультипоточности, специально сделанные для режима совместимости.

В OpenBlAS используются вычислительные кернелы вплоть до AVX512. Они определяются динамически.

 
Roman #:

Матлаб по умолчанию параллелит вычисления на все доступные ядра.
В mql5 это надо делать через OpenCL.
Поэтому не корректно будет сравнивать, если вычисления mql5 будут не через OpenCL.
Насчет CPU инструкций AVX, AVX2+FMA3 не знаю как онии выполняются в mql5, но сомневаюсь что параллелятся по умолчанию.
Просто за один такт процессорного времени, выполняется несколько математических операций, что не соответствует много ядерности.

Много математических операций параллелятся на все ядра ЦПУ автоматически в MQL5 при наличии AVX и выше.

За счет нативных типов матриц/векторов, массы встроенных методов у них + OpenBLAS, теперь математический код получается очень компактный, легкий для понимания и очень просто переносится из других систем.

Сейчас можно легко писать сложные нейросети на MQL5 - мат аппарата хватает.

 

Можно эту проблему как-то подправить ?

Не считает псевдообратную после 10000

void OnStart()
  {
   matrix data;
   data.Init(6,10000);
   data.Random(-10, 10);
   Print("Pinv \n", data.PInv());
  }
 
Renat Fatkhullin #:

Много математических операций параллелятся на все ядра ЦПУ автоматически в MQL5 при наличии AVX и выше.

За счет нативных типов матриц/векторов, массы встроенных методов у них + OpenBLAS, теперь математический код получается очень компактный, легкий для понимания и очень просто переносится из других систем.

Сейчас можно легко писать сложные нейросети на MQL5 - мат аппарата хватает.

Ренат, а почему в Маркете запрещены все расширения CPU?

 
Evgeniy Chernish #:

Можно эту проблему как-то подправить ?

Не считает псевдообратную после 10000

Считает.

Какой у Вас код ошибки (GetLastError)?

 
Slava #:

Считает.

Какой у Вас код ошибки (GetLastError)?

Это у меня проблема получается, не хватает памяти. Вопрос снимается

ERR_NOT_ENOUGH_MEMORY

4004

Недостаточно памяти для выполнения системной функции