Hello
i have a question about the Threads.
Hardeware: HP Zbook with i7 4700MQ
Software: Win8, Visual Studio 13 Professional SFML 2,3
My Programm process the numeric integral of Biot Savart with the euler technic.
https://en.wikipedia.org/wiki/Biot%E2%80%93Savart_lawIt has a vector with dim 3, every of this hould a dim 3 double vector as element.
Now the programm process every point (with natural numbers), x0-20(y0-20(z0-20)).
At every point it calculalte the magnet field vector and save it in the element of the "cube".
So i splitted the cube up in layers and gave every thread the same nummber of layers, the one, which where still not allocated to a thread, i pushed one at each thread, so long i had some layer in list.
In this example 20%4 => 4Threads*4+1Layers
Time to render:
Threads: Time in Minutes:
1. ca. 2:35
2. 1:49
3. 1:43
4. 1:37
8. 1:57
Whats going wrong?
The frustating thing is, with 4threads cpu at 70%, with 8. 100% but 4 are faster.
Maybe some information for me?
If someone want to see some other code, tell me
Regards,
Rarebit.
The code with thread handling.
int PartIntervall = game.DataBase.MagnetVectorList.size() / MaxThreads;
int PartIntervallRest = game.DataBase.MagnetVectorList.size() % MaxThreads;
vector<int> StartMod;
StartMod.resize(MaxThreads, 0);
vector<int> EndMod;
EndMod.resize(MaxThreads, 0);
for (int i = StartMod.size()-1; i > -1 && PartIntervallRest > 0 ; i--)
{
EndMod[i] = PartIntervallRest;
StartMod[i] = PartIntervallRest - 1;
PartIntervallRest--;
}
sf::Thread Thread1(bind(&forCoilMagneticFieldAtPointAsVector, &game, 0 + StartMod[0], PartIntervall + EndMod[0]));
sf::Thread Thread2(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall + StartMod[1], PartIntervall * 2 + EndMod[1]));
sf::Thread Thread3(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall * 2 + StartMod[2], PartIntervall * 3 + EndMod[2]));
sf::Thread Thread4(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall * 3 + StartMod[3], PartIntervall * 4 + EndMod[3]));
//sf::Thread Thread5(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall * 4 + StartMod[4], PartIntervall * 5 + EndMod[4]));
//sf::Thread Thread6(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall * 5 + StartMod[5], PartIntervall * 6 + EndMod[5]));
//sf::Thread Thread7(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall * 6 + StartMod[6], PartIntervall * 7 + EndMod[6]));
//sf::Thread Thread8(bind(&forCoilMagneticFieldAtPointAsVector, &game, PartIntervall * 7 + StartMod[7], PartIntervall * 8 + EndMod[7]));
Thread1.launch();
Thread2.launch();
Thread3.launch();
Thread4.launch();
//Thread5.launch();
//Thread6.launch();
//Thread7.launch();
//Thread8.launch();
sf::Thread Thread0(bind(&getProcess, &game)); //Überwachungsthread mit Fortschrittsanzeige
Thread0.launch();
Thread1.wait();
Thread2.wait();
Thread3.wait();
Thread4.wait();
//Thread5.wait();
//Thread6.wait();
//Thread7.wait();
//Thread8.wait();
Thread0.terminate();
The calculation function
void forCoilMagneticFieldAtPointAsVector(game* game, int StartIntervall, int EndIntervall)
{
for (size_t i = StartIntervall; i < EndIntervall; i++) //Jede grade Koordinate die Leiter abbarbeiten, hier zu beachten ist die Aufteilung den Würdfels in Scheiben
{
for (size_t y = 0; y < game->DataBase.MagnetVectorList[i].size(); y++)
{
for (size_t j = 0; j < game->DataBase.MagnetVectorList[i][y].size(); j++)
{
//Spulen abarbeiten
for (size_t CoilListCounter = 0; CoilListCounter < game->DataBase.CoilList.size(); CoilListCounter++)
{
coil CoilHolder = game->DataBase.CoilList[CoilListCounter]; //Kopier erstellen um Höhere Bandbreite zu Schaffen und jedem Thread schnellere Zugriffe zu ermöglichen
int MaxParts = CoilHolder.getMaxParts(game->DataBase.PartModivication); //Anzahl der Einzelteile der Spule
for (size_t Part = 0; Part < MaxParts; Part++)//eine Spule nach einer Genauigkeit abarbeiten
{
vector<double> vdPositionToNextPosition = vector_math_sub
(
CoilHolder.getPosition //erster Vektor mit Parametern
(
(CoilHolder.getLegth() / MaxParts)*Part
),
CoilHolder.getPosition //zweiter Vektor mit Parametern
(
(CoilHolder.getLegth() / MaxParts)*(Part + 1)
)
);
vector<double> vdDetectionPoint; //der Punkt an welchem gemessen wird als Input für Biot Savart, ist hier gegeben durch die Itteration der Graden Koordinatenpunkte
vdDetectionPoint.push_back(i);
vdDetectionPoint.push_back(y);
vdDetectionPoint.push_back(j);
game->DataBase.MagnetVectorList[i][y][j] = vector_math_add
(
game->DataBase.MagnetVectorList[i][y][j], //erster Vektor mit Parametern
biot_savart //zweiter Vektor mit Paramtern
(
vector_math_skalarmult(game->DataBase.LengthSImult, CoilHolder.getPosition((CoilHolder.getLegth() / MaxParts)*Part)),
vector_math_skalarmult(game->DataBase.LengthSImult, vdPositionToNextPosition),
vector_math_skalarmult(game->DataBase.LengthSImult, vdDetectionPoint),
1,
CoilHolder.getAmperage()
)
);
}
}
}
}
}
}