155 lines
4.2 KiB
MQL5
155 lines
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);
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
|