Visual studio 2015 OpenMP和在DLL中导出并行函数
我在DLL中有一个函数,它使用OpenMP来并行化几个循环。这些功能通过测试和导出,通过在C++中构建的应用程序调用,所有的工作都很好。然后,我将函数导出到另一个平台(MetaTrader Terminal 4,它使用Visual studio 2015 OpenMP和在DLL中导出并行函数,visual-studio-2015,parallel-processing,openmp,dllexport,mql4,Visual Studio 2015,Parallel Processing,Openmp,Dllexport,Mql4,我在DLL中有一个函数,它使用OpenMP来并行化几个循环。这些功能通过测试和导出,通过在C++中构建的应用程序调用,所有的工作都很好。然后,我将函数导出到另一个平台(MetaTrader Terminal 4,它使用MQL4编程语言),在该平台上,代码也可以工作,但速度要慢得多(请参阅下面使用OpenMP的代码片段)。所以我最好的猜测是,当从平台调用时,并行化不起作用。不过,我正在使用Visual Studio 2015进行我的项目 double dtime;
MQL4
编程语言),在该平台上,代码也可以工作,但速度要慢得多(请参阅下面使用OpenMP的代码片段)。所以我最好的猜测是,当从平台调用时,并行化不起作用。不过,我正在使用Visual Studio 2015进行我的项目
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 sin
for (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 sin
for (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();
从平台:
0.999997 dtime: 0.222026
0.917038 dtime: 0.219041
0.982879 dtime: 0.215614
0.723091 dtime: 0.219034
0.295653 dtime: 0.215915
0.097825 dtime: 0.21803
0.0350881 dtime: 0.21804
0.00654856 dtime: 0.219009
0.00188476 dtime: 0.217366
0.000435981 dtime: 0.223172
9.50818e-05 dtime: 0.21804
2.27348e-05 dtime: 0.260625
1.39124e-05 dtime: 0.219027
1.72161e-06 dtime: 0.218035
3.18178e-07 dtime: 0.218927
1.77708e-07 dtime: 0.218026
3.81575e-08 dtime: 0.204294
9.53867e-09 dtime: 0.221036
LIBRARY "LMBRDLL"
EXPORTS
getWeights
testWeights
MQL4
函数声明:
#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>
DLL
中的定义:
#include "stdafx.h"
double *getWeights( double const *idata,
int const *aTopology,
int topSize,
double const *aTV,
double validationDifference,
int vSize,
int tSteps,
int nVabs,
double *T
) {
vector<unsigned> topology(topSize);
for (i = 0; i < topSize; i++) {
topology[i] = aTopology[i];
}
vector<double> TV(2);
TV[0] = aTV[0];
TV[1] = aTV[1];
Matrix inputVals = buildInputs(idata, vSize, tSteps, nVabs);
inputVals = sortInputs(inputVals, TV);
sortTargets(TV);
Matrix targetVals = getTargets();
Net myNet(topology, inputVals);
double currentValidationError = 1000000000777;
double previousValidationError = 1000000000000000;
double difference = 1;
while (currentValidationError < previousValidationError) {
difference = previousValidationError - currentValidationError;
if (difference < validationDifference)
break;
FeedForward(&topology, &myNet);
Backpropagation(&topology, &myNet, &targetVals);
BuildJacobian(&topology, &myNet);
LevenberMarquardtBeyesianRegularization( &topology,
&myNet,
&targetVals
);
previousValidationError = currentValidationError;
currentValidationError = Validation( &myNet.allLMweights,
topology
);
//UpdateSynapses(topology, myNet);
}
vector<double> rowWeights = buildRWeights(myNet.allSynapses);
for (i = 0; i < rowWeights.size(); i++) {
T[i] = rowWeights[i];
}
return T;
}
double testWeights( double const *rowWeights,
double const *testData,
int const *aTopology,
int topSize,
int timeSteps,
int nVariables
) {
vector<unsigned> topology(topSize);
for (i = 0; i < topSize; i++) {
topology[i] = aTopology[i];
}
vector<Matrix> testWeights = buildWeightMatrices( rowWeights,
topology
);
vector<double> input = buildTestInputs( testData,
timeSteps,
nVariables
);
double output = getOutput(testWeights, input);
return output;
}
< > > >代码> Heal/> > >强> >导出到C++应用程序:
#include "stdafx.h"
using namespace std;
__declspec(dllexport) double *getWeights( double const *idata,
int const *aTopology,
int topSize,
double const *aTV,
double validationDifference,
int vSize,
int tSteps,
int nVabs,
double *T
);
__declspec(dllexport) double testWeights( double const *rowWeights,
double const *testData,
int const *aTopology,
int topSize,
int timeSteps,
int nVariables
);
你有没有检查过你是否真的使用了和产生的线程数量一样多的内核?您的MQL4 thingy很可能会生成进程到核心的关联,这将由OpenMP线程继承,从而防止它们使用除应用程序最初使用的内核之外的所有其他(空闲)内核。。。不过这只是瞎猜。请您发布调用的完整
MQL4
-上下文,好吗?即{*.mq4 |*.mqh |…}
文件的相关片段,包括#strict代码>等指令和导入代码>节和所有其他编译修改指令——如果没有这些MetaTrader终端特定的事实,就不可能以任何合理的方式帮助您。无论如何,Adrijus,欢迎来到MQL
StackOverflow的野生世界,它鼓励用户发布问题,即MCVE-一个观察到的问题的最小完整可验证示例,我们努力从社区成员那里获得帮助。更新帖子并完成上面提到的MQL4
-代码,以形成MCVE是公平的。很抱歉,回复太晚了。我刚刚更新了问题的更多细节,我希望这些细节足以让我了解我所面临的问题。如果你还有什么需要知道的,请发表评论。就目前而言,MQL4
代码是否计划成为MetaTrader终端代码执行领域中的自定义指示器
、脚本
或专家顾问
?您是否检查过是否确实使用了与生成的线程数量相同的内核?您的MQL4 thingy很可能会生成进程到核心的关联,这将由OpenMP线程继承,从而防止它们使用除应用程序最初使用的内核之外的所有其他(空闲)内核。。。不过这只是瞎猜。请您发布调用的完整MQL4
-上下文,好吗?即{*.mq4 |*.mqh |…}
文件的相关片段,包括#strict代码>等指令和导入代码>节和所有其他编译修改指令——如果没有这些MetaTrader终端特定的事实,就不可能以任何合理的方式帮助您。无论如何,Adrijus,欢迎来到MQL
StackOverflow的野生世界,它鼓励用户发布问题,即MCVE-一个观察到的问题的最小完整可验证示例,我们努力从社区成员那里获得帮助。更新帖子并完成上面提到的MQL4
-代码,以形成MCVE是公平的。很抱歉,回复太晚了。我刚刚更新了问题的更多细节,我希望这些细节足以让我了解我所面临的问题。如果你还有什么需要知道的,请发表评论。就目前而言,MQL4
代码是否计划成为MetaTrader终端代码执行领域中的自定义指示符
、脚本
或专家顾问
?
LIBRARY "LMBRDLL"
EXPORTS
getWeights
testWeights
#include "stdafx.h"
using namespace std;
__declspec(dllexport) double *getWeights( double const *idata,
int const *aTopology,
int topSize,
double const *aTV,
double validationDifference,
int vSize,
int tSteps,
int nVabs,
double *T
);
__declspec(dllexport) double testWeights( double const *rowWeights,
double const *testData,
int const *aTopology,
int topSize,
int timeSteps,
int nVariables
);