2012-07-31 4 views
0

Donc voici le problème. J'ai un morceau de code qui, lorsqu'il est exécuté dans un seul thread, fonctionne parfaitement. Mais une fois que ce code est appelé avec TBB, il a gelé (ou je n'ai juste pas la patience d'attendre que ça finisse!).exécution parallèle dans TBB gèle

Le code est trop long, mais imaginez ceci:

class TBB_Test 
{ 
public: 
    TBB_Test(void) { /* initialize the stuff */ } 

    void operator() (tbb::blocked_range<int> &r) const 
    { 
    for (int i = r.begin(); i != r.end(); ++i) 
    { 
     // compute very awesome stuff! 
    } 
    } 
}; 

Alors, quand je l'exécute en séquentiel:

TBB_Test() (tbb::blocked_range<int>(0, max_value)); 

cela fonctionne, mais une fois en parallèle:

tbb::parallel_for(tbb::blocked_range<int>(0, max_value, grainsize), TBB_Test()); 

il a gelé au lieu d'être plus rapide que le séquentiel.

Qu'est-ce qui pourrait causer une telle chose? Deux threads essayant de lire ou d'écrire au même endroit? Dans notre cas, l'écriture ne devrait pas arriver! Et nous avons d'autres situations où la même adresse est probablement lue par plusieurs threads et ne gèle pas!

Une idée?

Dans VStudio, au moins là, lors du débogage, il suffit de l'activer pour que le débogueur s'arrête à toutes sortes d'exceptions ... longtemps, mais la bonne façon de le faire!

+2

Je vais "wtf" quand les gens utilisent "tla" comme "tbb";) – paulsm4

+0

PS: Avez-vous traversé tout cela dans le débogueur? Quand il "gèle", est-ce dans une boucle infinie? Bloqué? Impasse? Y a-t-il des globals sur lesquels vos threads pourraient marcher? Etc etc – paulsm4

+0

le débogueur par défaut dans VS ne sert pas à attraper quelque chose de mal ... et en essayant de le parcourir en parallèle, ne sais pas comment! J'ai isolé le problème à un seul appel de fonction maintenant. Toujours en train d'analyser ... mais j'espère apprendre plus de truc aussi avec TBB! Donc, si vous avez résolu un problème similaire en vérifiant une chose en particulier, cela pourrait être utile! – widgg

Répondre

0

Donc, naturellement, c'était un problème d'allocation de mémoire.

La mauvaise solution consiste à utiliser mutex où la mémoire est allouée. C'est mauvais parce que vous vous retrouvez avec vos processeurs X fonctionnant au maximum ... la plupart du temps en attente sur mutex.

L'approche finale que nous avons utilisée est que chaque tranche avait son schéma d'allocation de mémoire. Ensuite, en utilisant une "jointure", nous fusionnons les données ensemble après leur calcul. Ainsi, le processeur fonctionne sans mutex. Mais cela cause beaucoup plus de mémoire. Mais comme il n'y a pas de duplication entre les threads, ça devrait aller!

Alors, leçon apprise!

Questions connexes