155 lines
No EOL
4.2 KiB
MQL5
155 lines
No EOL
4.2 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| MatMulBench.mq5 |
|
|
//| Benchmark: matrix nativo vs manual vs array |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Benchmark"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 1) Multiplicación MANUAL usando el tipo matrix (indexado a mano) |
|
|
//+------------------------------------------------------------------+
|
|
bool MatMulManual(const matrix &A, const matrix &B, matrix &C)
|
|
{
|
|
ulong n = A.Rows();
|
|
ulong k = A.Cols();
|
|
ulong m = B.Cols();
|
|
|
|
if(B.Rows() != k)
|
|
return false;
|
|
|
|
C = matrix::Zeros(n, m);
|
|
|
|
for(ulong i = 0; i < n; i++)
|
|
{
|
|
for(ulong j = 0; j < m; j++)
|
|
{
|
|
double sum = 0.0;
|
|
for(ulong p = 0; p < k; p++)
|
|
sum += A[i][p] * B[p][j];
|
|
C[i][j] = sum;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 2) Multiplicación NATIVA (operador MatMul de matrix) |
|
|
//+------------------------------------------------------------------+
|
|
bool MatMulNative(const matrix &A, const matrix &B, matrix &C)
|
|
{
|
|
C = A.MatMul(B);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| 3) Multiplicación emulando matrix con double[] planos (row-major)|
|
|
//+------------------------------------------------------------------+
|
|
bool MatMulArray(const double &A[], const double &B[], double &C[],
|
|
int n, int k, int m)
|
|
{
|
|
ArrayResize(C, (int)(n * m));
|
|
ArrayInitialize(C, 0.0);
|
|
|
|
for(int i = 0; i < n; i++)
|
|
{
|
|
for(int j = 0; j < m; j++)
|
|
{
|
|
double sum = 0.0;
|
|
int aBase = i * k;
|
|
for(int p = 0; p < k; p++)
|
|
sum += A[aBase + p] * B[p * m + j];
|
|
C[i * m + j] = sum;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Helpers para llenar con datos aleatorios |
|
|
//+------------------------------------------------------------------+
|
|
matrix RandMatrix(ulong rows, ulong cols)
|
|
{
|
|
matrix m(rows, cols);
|
|
for(ulong i = 0; i < rows; i++)
|
|
for(ulong j = 0; j < cols; j++)
|
|
m[i][j] = (double)MathRand() / 32767.0;
|
|
return m;
|
|
}
|
|
|
|
void RandArray(double &arr[], int n, int m)
|
|
{
|
|
ArrayResize(arr, n * m);
|
|
for(int i = 0; i < n * m; i++)
|
|
arr[i] = (double)MathRand() / 32767.0;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Script program start function |
|
|
//+------------------------------------------------------------------+
|
|
void OnStart()
|
|
{
|
|
const int N = 600; // dimensión de las matrices NxN
|
|
const int ITER = 300; // repeticiones
|
|
|
|
MathSrand(42);
|
|
|
|
//--- Preparar datos base (matrix)
|
|
matrix Am = RandMatrix(N, N);
|
|
matrix Bm = RandMatrix(N, N);
|
|
|
|
//--- Preparar datos base (array plano)
|
|
double Aa[], Ba[];
|
|
ArrayResize(Aa, N * N);
|
|
ArrayResize(Ba, N * N);
|
|
for(int i = 0; i < N; i++)
|
|
for(int j = 0; j < N; j++)
|
|
{
|
|
Aa[i * N + j] = Am[i][j];
|
|
Ba[i * N + j] = Bm[i][j];
|
|
}
|
|
|
|
double checksum = 0.0;
|
|
|
|
//=== 1) Manual con matrix ===
|
|
{
|
|
matrix C;
|
|
ulong a = GetMicrosecondCount();
|
|
for(int it = 0; it < ITER; it++)
|
|
{
|
|
MatMulManual(Am, Bm, C);
|
|
checksum += C[0][0];
|
|
}
|
|
ulong b = GetMicrosecondCount();
|
|
Print("1) Manual (matrix indexado): ", (b - a), " us checksum=", checksum);
|
|
}
|
|
|
|
//=== 2) Nativo MatMul ===
|
|
{
|
|
matrix C;
|
|
checksum = 0.0;
|
|
ulong a = GetMicrosecondCount();
|
|
for(int it = 0; it < ITER; it++)
|
|
{
|
|
MatMulNative(Am, Bm, C);
|
|
checksum += C[0][0];
|
|
}
|
|
ulong b = GetMicrosecondCount();
|
|
Print("2) Nativo (A.MatMul(B)): ", (b - a), " us checksum=", checksum);
|
|
}
|
|
|
|
//=== 3) Emulado con double[] ===
|
|
{
|
|
double C[];
|
|
checksum = 0.0;
|
|
ulong a = GetMicrosecondCount();
|
|
for(int it = 0; it < ITER; it++)
|
|
{
|
|
MatMulArray(Aa, Ba, C, N, N, N);
|
|
checksum += C[0];
|
|
}
|
|
ulong b = GetMicrosecondCount();
|
|
Print("3) Array double[] (row-major):", (b - a), " us checksum=", checksum);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+ |