Je dispose à l'origine d'une boucle mono-thread qui itère sur tous les pixels d'une image et peut effectuer diverses opérations sur les données.
La bibliothèque que j'utilise dicte que la récupération des pixels d'une image doit se faire ligne par ligne. Pour ce faire, j'alloue dynamiquement un bloc de mémoire pouvant contenir une rangée de pixels (BMM_Color_fl
est une structure contenant les données RGBA d'un pixel sous forme de quatre valeurs flottantes, et GetLinearPixels()
copie une rangée de pixels depuis une bitmap dans un tableau BMM_Color_fl
.)
BMM_Color_fl* ligne = (BMM_Color_fl*)malloc(largeur * sizeof(BMM_Color_fl));
for (int y = 0; y < hauteur; y++)
{
bmp->GetLinearPixels(0, y, largeur, ligne); //Copie des données de la rangée Y depuis la bitmap dans la ligne.
BMM_Color_fl* pixel = ligne; //Récupérer le premier pixel de la ligne.
for (int x = 0; x < largeur; x++, pixel++) // Pour chaque pixel dans la rangée...
{
//Faire quelque chose avec un pixel.
}
}
free(ligne);
Jusqu'ici tout va bien!
Dans le but de réduire le temps d'exécution de cette boucle, j'ai écrit une version concurrente utilisant parallel_for
, qui ressemble à ceci :
parallel_for(0, hauteur, [&](int y)
{
BMM_Color_fl* ligne = (BMM_Color_fl*)malloc(largeur * sizeof(BMM_Color_fl));
bmp->GetLinearPixels(0, y, largeur, ligne);
BMM_Color_fl* pixel = ligne;
for (int x = 0; x < largeur; x++, pixel++)
{
//Faire quelque chose avec un pixel.
}
free(ligne);
});
Alors que la boucle multithread est déjà plus rapide que l'originale, je réalise qu'il est impossible pour tous les threads d'utiliser le même bloc de mémoire, donc actuellement j'alloue et libère la mémoire à chaque itération de la boucle, ce qui est évidemment gaspilleur car il n'y aura jamais plus de threads que d'itérations de boucle.
Ma question est la suivante : comment puis-je faire en sorte que chaque thread alloue exactement un tampon de ligne et l'utilise de manière répétée (et idéalement, le libère à la fin) ?
- Je dois préciser que je suis un utilisateur novice de C++.
Implémentation des solutions suggérées :
Concurrency::combinable> ligne;
parallel_for(0, hauteur, [&] (int y)
{
std::vector ligneL = ligne.local();
if (ligneL.capacity() < largeur) ligneL.reserve(largeur);
bmp->GetLinearPixels(0, y, largeur, &ligneL[0]);
for (int x = 0; x < largeur; x++)
{
BMM_Color_fl* pixel = &ligneL[x];
//Faire quelque chose avec un pixel.
}
});
Comme suggéré, j'ai abandonné le malloc
et l'ai remplacé par un vector
+reserve
.