I have a function within DLL that uses OpenMP to parallelize few loops.
The functions have been tested/exported by calling them from an app
built in C++ and everything works nicely (method used for linking). I then export the functions to
MQL4 (method used for linking)
where the code also works but substantially slower. I am
using Visual Studio 2015 for creating the DLL. I strongly suspect that
parallelization is not working while calling from the MQL4. Is it something to do with MQL4 or the DLL it-self?
Loops that contributes to overall slowdown:
double dtime;
dtime = omp_get_wtime();
ofstream fopen("C:\\output.txt", 'a');
ofstream fout("C:\\output.txt", 'a');
dtime = omp_get_wtime();
#pragma omp parallel for num_threads(num)
for (int p = 1; p <= r1; p++) {
int k = omp_get_thread_num();
int i = I1[p], j = i + l;
double alpha = 0, beta = 0, gamma = 0;
double zeta, t, c, s;
for (int k = 0; k < N; k++) {
alpha = alpha + (U_t[i][k] * U_t[i][k]);
beta = beta + (U_t[j][k] * U_t[j][k]);
gamma = gamma + (U_t[i][k] * U_t[j][k]);
}
C[k] = max(C[k], abs(gamma) / sqrt(alpha*beta));
//converge = max(converge, abs(gamma)/sqrt(alpha*beta)); //compute convergence//basicaly is the angle//between column i and j
zeta = (beta - alpha) / (2.0 * gamma);
t = sgn(zeta) / (abs(zeta) + sqrt(1.0 + (zeta*zeta))); //compute tan of angle
c = 1.0 / (sqrt(1.0 + (t*t))); //extract cos
s = c*t; //extrac sinfor (int k = 0; k<N; k++) {
t = U_t[i][k];
U_t[i][k] = c*t - s*U_t[j][k];
if (!(U_t[i][k] < 0 || U_t[i][k] > 0)) {
U_t[i][k] = 0;
}
U_t[j][k] = s*t + c*U_t[j][k];
if (!(U_t[j][k] < 0 || U_t[j][k] > 0)) {
U_t[j][k] = 0;
}
t = V_t[i][k];
V_t[i][k] = c*t - s*V_t[j][k];
if (!(V_t[i][k] < 0 || V_t[i][k] > 0)) {
V_t[i][k] = 0;
}
V_t[j][k] = s*t + c*V_t[j][k];
if (!(V_t[j][k] < 0 || V_t[j][k] > 0)) {
V_t[j][k] = 0;
}
}
}
fout << endl;
#pragma omp parallel for num_threads(num)
for (int p = 1; p <= r2; p++) {
int k = omp_get_thread_num();
int i = I2[p], j = i + l;
double alpha = 0, beta = 0, gamma = 0;
double zeta, t, c, s;
for (int k = 0; k < N; k++) {
alpha = alpha + (U_t[i][k] * U_t[i][k]);
beta = beta + (U_t[j][k] * U_t[j][k]);
gamma = gamma + (U_t[i][k] * U_t[j][k]);
}
C[k] = max(C[k], abs(gamma) / sqrt(alpha*beta));
//converge = max(converge, abs(gamma)/sqrt(alpha*beta)); //compute convergence//basicaly is the angle//between column i and j
zeta = (beta - alpha) / (2.0 * gamma);
t = sgn(zeta) / (abs(zeta) + sqrt(1.0 + (zeta*zeta))); //compute tan of angle
c = 1.0 / (sqrt(1.0 + (t*t))); //extract cos
s = c*t; //extrac sinfor (int k = 0; k<N; k++) {
t = U_t[i][k];
U_t[i][k] = c*t - s*U_t[j][k];
if (!(U_t[i][k] < 0 || U_t[i][k] > 0)) {
U_t[i][k] = 0;
}
U_t[j][k] = s*t + c*U_t[j][k];
if (!(U_t[j][k] < 0 || U_t[j][k] > 0)) {
U_t[j][k] = 0;
}
t = V_t[i][k];
V_t[i][k] = c*t - s*V_t[j][k];
if (!(V_t[i][k] < 0 || V_t[i][k] > 0)) {
V_t[i][k] = 0;
}
V_t[j][k] = s*t + c*V_t[j][k];
if (!(V_t[j][k] < 0 || V_t[j][k] > 0)) {
V_t[j][k] = 0;
}
}
}
fout << endl;
for (int k = 0; k < num; k++)
converge = max(converge, C[k]);
fout << endl;
if (l == M) {
fout << converge << '\t';
fout << endl;
dtime = omp_get_wtime() - dtime;
fout << "\n" << "dtime: " << dtime << " ";
dtime = omp_get_wtime();
fout << endl;
}
fout << endl;
fout.close();
#property copyright"Adrijus"#property version"1.00"#property strict#import "LMBRDLL.dll"double getWeights(double &data[], int &topology[], int topSize, double &TV[], double validationDifference, int vSize, int timeSteps, int nVabs, double &weights[]);
double testWeights(double &weights[], double ¤tData[], int &topology[], int topSize, int timeSteps, int nVabs);
#import
#include <stdlib.mqh>
This step-by-step walkthrough shows how to create a dynamic link library (DLL) for use with a C++ app. Using a library is a great way to reuse code. Rather than re-implementing the same routines in every program that you create, you write them one time and then reference them from apps that require the functionality. By putting code in the DLL...
I have a function within DLL that uses OpenMP to parallelize few loops. The functions have been tested/exported by calling them from an app built in C++ and everything works nicely (method used for linking). I then export the functions to MQL4 (method used for linking) where the code also works but substantially slower. I am using Visual Studio 2015 for creating the DLL. I strongly suspect that parallelization is not working while calling from the MQL4. Is it something to do with MQL4 or the DLL it-self?
Loops that contributes to overall slowdown:
These are outputs for convergence and time taken:
C++ app:
From MetaTrader4:
MQL4 function declarations:
MQL4 function calls:
Definitions in the DLL:
LMBRDLL.def for exporting to MetaTrader platform:
LIBRARY "LMBRDLL" EXPORTS getWeights testWeightsHeaderDLL.h for exporting to C++ app: