Ich möchte mit OpenMP eine for-Schleife innerhalb einer Funktion, die von der Haupt in C++ aufgerufen wird, parallelisieren.OpenMP langsame private Funktion
Mein Code läuft viel langsamer als im sequentiellen Modus: Die For-Schleife dauert etwa 6,1s (Wall-Clock) ohne OpenMP (nur den Befehl #pragma ... auskommentieren), und 11,8s mit OpenMP.
Meine Maschine verfügt über 8 CPUs und 8183MB physischen Speicher und ist mit einem 64-Bit-Windows 7-Betriebssystem ausgestattet. Ich benutze den Visual Studio Compiler für ein 64x Bit System im Debug Modus.
Ich habe gelesen, dass Leistungseinbußen durch Variablen verursacht werden können, die als privat deklariert werden sollten, aber ich bin nicht sicher, wie dies richtig zu tun ist und welche der Variablen als privat deklariert werden müssen.
Dies ist relevant für-Schleife:
vec DecenterOffsetParallel(const real_1d_array &x22, vec vDistance, double dOffsetXp, double dOffsetYp, double dOffsetXm, double dOffsetYm, double dOffsetXpY, double dOffsetYpX, double dOffsetXmY, double dOffsetYmX, double* dDeltaXp, double* dDeltaYp, double* dDeltaXm, double* dDeltaYm, double* dDeltaXpY, double* dDeltaYpX, double* dDeltaXmY, double* dDeltaYmX, double* delta0, /*local variables for the parallel code: */ const int nRaysn, double PupilDian, mat mRxNn, mat mRyNn, mat mRzNn, mat mRxN1n, mat mRyN1n, mat mRzN1n, mat mRxN2n, mat mRyN2n, mat mRzN2n, mat mRxN3n, mat mRyN3n, mat mRzN3n, mat mRcxNn, mat mRcyNn, mat mRczNn, mat mRcxN1n, mat mRcyN1n, mat mRczN1n, mat mRcxN2n, mat mRcyN2n, mat mRczN2n, mat mRcxN3n, mat mRcyN3n, mat mRczN3n, mat mPathNn, mat mPath1Nn, mat mPath00Nn, mat mPathN1n, mat mPath1N1n, mat mPath00N1n, mat mPathN2n, mat mPath1N2n, mat mPath00N2n, mat mPathN3n, mat mPath1N3n, mat mPath00N3n)
{
#pragma omp parallel for
for (int xy = 0; xy < nRaysn * nRaysn; xy++){
mat temp = mat(nRaysn, nRaysn);
mat mScxn(nRaysn, nRaysn);
mat mScyn(nRaysn, nRaysn);
mat mSczn(nRaysn, nRaysn);
int i = xy/nRaysn;
int j = xy % nRaysn;
// only rays inside entrance pupil:t
if (sqrt(((10.0/nRaysn) * i - 5.0)*((10.0/nRaysn) * i - 5.0) + ((10.0/nRaysn)*j - 5.0) *((10.0/nRaysn)*j - 5.0)) <= PupilDian/2.0){
// Initialize the matrices
mRxNn(i, j) = (10.0/nRaysn) * i - 5.0;
mRyNn(i, j) = (10.0/nRaysn) * j - 5.0;
mRzNn(i, j) = 0.0;
//... everything is repeated 3 more times to simulate all in all 4 cases...: mRxNn1(i,j) = (10.0/nRaysn)*i-5.0; and so on...
mRcxNn(i, j) = sign(vDistance(0)) *(mRxNn(i, j) - dOffsetYmX)/(sqrt(vDistance(0)*vDistance(0) + (mRxNn(i, j) - dOffsetYmX) * (mRxNn(i, j) - dOffsetYmX) + (mRyNn(i, j) - dOffsetYm) *(mRyNn(i, j) - dOffsetYm)));
mRcyNn(i, j) = sign(vDistance(0)) *(mRyNn(i, j) - dOffsetYm)/(sqrt(vDistance(0)*vDistance(0) + (mRxNn(i, j) - dOffsetYmX) * (mRxNn(i, j) - dOffsetYmX) + (mRyNn(i, j) - dOffsetYm) *(mRyNn(i, j) - dOffsetYm)));
mRczNn(i, j) = sqrt(1 - mRcxNn(i, j)*mRcxNn(i, j) - mRcyNn(i, j)*mRcyNn(i, j));
mPathNn(i, j) = 0.0;
mPath1Nn(i, j) = sign(vDistance(0)) *nAir * vDistance(0)/mRczNn(i, j);
mPath00Nn(i, j) = mPath1Nn(i, j);
//... everything is repeated 3 more times to simulate 4 different cases...
//trace rays through cornea
temp(i, j) = RayIntersect(ZernAnt, ZernRadAnt, &mRxNn(i, j), &mRyNn(i, j), P2DAnt, UAnt, VAnt, &mRzNn(i, j), mRcxNn(i, j), mRcyNn(i, j), mRczNn(i, j), &mPathNn(i, j), xNullAnt, yNullAnt, NknotsUAnt, NknotsVAnt); // find the intersection (modifies mRz, mRy, mRx, mPath)
mPathNn(i, j) = mPath1Nn(i, j) + nAir*mPathNn(i, j);
temp(i, j) = Surface(P2DAnt, UAnt, VAnt, ZernAnt, ZernRadAnt, mRxNn(i, j), mRyNn(i, j), mRzNn(i, j), &mScxn(i, j), &mScyn(i, j), &mSczn(i, j), KnotIntervallSizeAnt, xNullAnt, yNullAnt);
// *Ant are identical for all four cases!
temp(i, j) = Refract(nAir, nCornea, &mRcxNn(i, j), &mRcyNn(i, j), &mRczNn(i, j), mScxn(i, j), mScyn(i, j), mSczn(i, j));
//... everything is repeated 3 more times to simulate all in all 4 cases...
}
else{
mRxNn(i, j) = mRyNn(i, j) = mRzNn(i, j) = mRcxNn(i, j) = mRcyNn(i, j) = mRczNn(i, j) = mPathNn(i, j) = mPath1Nn(i, j) = NAN;
//... everything is repeated 3 more times to simulate all in all 4 cases...
}
}
// some other stuff, that is not relevant to the questions...
}
Kann mir jemand einen Tipp geben, was könnte die Leistungseinbußen führen? Vielen Dank!
PS: Armadillo-Bibliothek wird für die Matrizen und Vektoren verwendet.
'public' oder' private' wird in dieser Hinsicht nichts ändern. –
Willkommen bei SO. Leider liefern Sie keine ausreichenden Informationen, um Ihre Frage richtig zu beantworten. Bitte fügen Sie eine [mcve] ein, beschreiben Sie Ihre Systemkonfiguration (CPU, Speicher, Compiler) und wie messen Sie und Ihre spezifischen Messergebnisse. – Zulan
Ich habe die Systeminformationen hinzugefügt und das vereinfachte Beispiel durch den (leicht gekürzten) Originalcode aus meinem Programm ersetzt. Hoffe das hilft! – Sims