2015-08-26 1 views
0

J'essaye de coder une chaîne de Markov multicode en C++ et pendant que j'essaie de tirer parti des nombreux processeurs (jusqu'à 24) pour exécuter une chaîne différente dans chacun d'eux, j'ai un problème en choisissant un bon conteneur pour recueillir le résultat des évaluations numériques sur chaque CPU. Ce que j'essaie de mesurer est essentiellement la valeur moyenne d'un tableau de variables booléennes. J'ai essayé coder une enveloppe autour d'un `std :: vector`` objet ressemblant à ce que:C++ pile efficace pour application multicore

struct densityStack { 
    vector<int> density; //will store the sum of boolean varaibles 
    int card; //will store the amount of elements we summed over for normalizing at the end 

    densityStack(int size){ //constructor taking as only parameter the size of the array, usually size = 30 
     density = vector<int> (size, 0); 
     card = 0; 
     } 

    void push_back(vector<int> & toBeAdded){ //method summing a new array (of measurements) to our stack 
     for(auto valStack = density.begin(), newVal = toBeAdded.begin(); valStack != density.end(); ++valStack, ++ newVal) 
      *valStack += *newVal; 
     card++; 
     } 

    void savef(const char * fname){ //method outputting into a file 
     ofstream out(fname); 
     out.precision(10); 
     out << card << "\n"; //saving the cardinal in first line 
     for(auto val = density.begin(); val != density.end(); ++val) 
      out << << (double) *val/card << "\n"; 
     out.close(); 
     } 
}; 

Alors, dans mon code, j'utiliser un seul objet densityStack et chaque fois un noyau de CPU dispose de données (peut être 100 fois par seconde), il appellera push_back pour renvoyer les données à densityStack. Mon problème est que cela semble être plus lent que la première approche brute où chaque noyau stocké chaque tableau de mesure dans le fichier, puis j'utilisais un script Python pour moyenne et propre (je n'étais pas content parce que trop de stockage informations et induisant trop de stress inutile sur les disques durs).

Voyez-vous où je peux perdre beaucoup de performance? Je veux dire y at-il une source de frais généraux évidents? Parce que pour moi, copier le vecteur même à des fréquences de 1000Hz ne devrait pas être trop.

+0

Si le code fonctionne correctement, cela peut être plus approprié pour [Code Review] (http://codereview.stackexchange.com/) –

+0

"chaque fois qu'un coeur de processeur a des données, il appellera push_back" - où est le mutex guarding ce? Oubliez efficace, commencez avec le code correct. La bonne façon de faire l'accumulation multi-core est d'accumuler des subsums par thread, puis de les combiner. – MSalters

+0

Je suis allé de l'avant et j'ai supprimé mon commentaire car il s'agissait plus d'une suggestion «essayez ceci» qu'une réponse. Cependant, pour @MSalters sur l'ajout d'un mutex: je ne vois pas l'avantage d'un mutex pour un vecteur qui va rester une taille unique, ne sera jamais déplacé, seulement des opérations d'addition seront invoquées dessus. Je ne vois rien de dangereux à ce sujet. Dans mon propre intérêt d'apprentissage: qu'est-ce qui pourrait être corrompu/mal tourner dans ce scénario? (J'ignore intentionnellement la méthode savef pour cette pensée) – Diniden

Répondre

2

Comment synchronisez-vous votre instance densityStack partagée?

De l'information limitée ici, je suppose que les processeurs sont bloqués en attente d'écrire des données chaque fois qu'ils ont un petit morceau de données. Si tel est le problème, une technique simple pour améliorer les performances serait de réduire le nombre d'écritures. Conservez un tampon de données pour chaque CPU et écrivez moins souvent dans densityStack.