Visual studio 2015 OpenMP和在DLL中导出并行函数

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;

我在DLL中有一个函数,它使用OpenMP来并行化几个循环。这些功能通过测试和导出,通过在C++中构建的应用程序调用,所有的工作都很好。然后,我将函数导出到另一个平台(MetaTrader Terminal 4,它使用
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 &currentData[],
                                          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
                                              );