paralléliser le remplissage d'une matrice bitmap avec GDI+ C++
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

paralléliser le remplissage d'une matrice bitmap avec GDI+ C++



  1. #1
    mp3dux

    paralléliser le remplissage d'une matrice bitmap avec GDI+ C++


    ------

    Salut à tous,

    j'ai un programme qui affiche un matrice bitmap à l’écran, disons à intervalle de quelques millisecondes.

    la bitmap peut contenir une nombre de case variable que je colorie avec l'instruction "FillRectangle".

    Le problème est que je dois colorier les unes après les autres chacune des cases...

    Et comme je peux avoir 1 million de cases, le programme ralentie fortement car tou se fait en séquentiel, ainsi j cherche à parralléliser

    cette fonction sans trouver pour l'instant aucune solution.

    Là je pense que j'en ai 10 000 mais à 1 million je pleure...

    merci de votre aide.

    Nom : automate1.PNG
Affichages : 101
Taille : 79,1 Ko

    -----
    Si nous faisions tout ce que nous sommes capables de faire, nous en serions abasourdis. T.E

  2. #2
    polo974

    Re : paralléliser le remplissage d'une matrice bitmap avec GDI+ C++

    Salut à toi,
    peux-tu être plus explicite dans ta question, car, là, je pense que tu es tellement dans ta problématique que tu as oublié de nous dire beaucoup de choses pour qu'on puisse t'aider efficacement.
    Jusqu'ici tout va bien...

  3. #3
    mp3dux

    Re : paralléliser le remplissage d'une matrice bitmap avec GDI+ C++

    merci polo pour la réflexion.

    voilà en fait j'ai un programme d'automate cellulaire, que j'aimerais optimiser pour gagner en vitesse d’affiche. Le fonctionnement du programme se définit comme suivant :

    1-Les cellules sont des carrés d'une matrice dont je définie le nombre.

    2-Au démarrage chaque cellule peut prendre deux valeurs possibles(true =vivant, false =morte)

    3-L'état de chaque cellule évolue à l'instant t1 en fonction du nombre de cellules qui l'entourent au temps t0.

    4-La matrice évolue ainsi de t(0)->t(n) avec n qui tend vers l'infinie.

    5-Ainsi à l’instant t(n) par exemple, je fige la matrice, je relève les valeurs pour calculer le nouvel état à t(n+1).



    Le programme contient deux boucles de calculs principales.
    -la première est celle qui calcule la valeur que prendra chaque cellule à l'instant suivante.
    -la seconde est celle qui utilise GDI+ (graphics.FillRectangle) pour tracer la couleur de chaque cellule en fonction de la valeur calculée.

    L'affichage est fluide lorsque que j'ai 100*100 par exemple, 10 000 cellules à traiter une par une ça passe.

    quand je passe à 1000*1000, =>1 million de cellules à traiter, l’affichage devient très lente et pourtant j'ai une charge de processeur qui ne dépasse jamais 25% au total et jamais 50% par coeur. Le programme passe la majorité de son temps dans la boucle d'affichage.

    j'ai cherché pas mal de solution sur le net et après plusieurs tests, j'ai gardé openMP qui s'avère de très loin le plus efficace comparé à parrallel_for de la bibliothèque<ppl> et parrallel_for_fixed.

    j'ai ainsi optimisé la première boucle de calcul qui divise la boucle sur 4 threads, chaque cpu calcule le quart de la boucle, ça n'a pas apporté grand chose, pratiquement rien car le gros du temps est passé dans la boucle d'affichage.

    Cependant je n'ai trouvé aucune solution pour partager le travail entre les 4 coeurs. GDI+ ne supportant pas les threads apparemment.


    Quelqu’un pourrait m'aider pour augmenter la fluidité svp ? En gros j'aimerais au ieu de dessiner les cases une à une sur un seul cpu, chaque cpu dessine en parallèle le quart de la bitmap.

    code coeur de la boucle d'affichage
    Code:
    for(int colonne=0;colonne<m_nTaille;colonne++)//pour chaque colone de la  ligne choisie
    		{
    
    			if ( m_Cellules[ligne*m_nTaille+colonne] == true)
    			
    			{	
    				g.FillRectangle(&CaseVivante, ZonesCellule); //couleur "CaseVivante" pour la cellule vivante
    			}
    		
    			else
    
    			{
    				g.FillRectangle(&CaseMorte, ZonesCellule);//couleur "CaseMorte" pour la cellule morte
    			}
    }
    Si nous faisions tout ce que nous sommes capables de faire, nous en serions abasourdis. T.E

  4. #4
    polo974

    Re : paralléliser le remplissage d'une matrice bitmap avec GDI+ C++

    Bon, ça fait un certain temps, voire un temps certain que je n'ai plus touché au coté obscur de l'informatique ( ), mais, bon, quand on regarde la doc: "Familiarity with the Windows graphical user interface and message-driven architecture is required. ", il est assez probable que chaque requête passe par le système de messagerie, bref, on brasse beaucoup d'octets pour chaque appel.

    Donc, je prendrais le pb autrement:
    définir un bitmap en mémoire correspondant à la matrice (1 cellule=1 pixel), travailler direct dans le bitmap et une fois calculé, balancer le bitmap à l'écran d'un coup d'un seul avec zoom si besoin pour les petites matrices.
    si besoin bosser en double buffer pour avoir l'état n-1 durant le calcul de n+1, et en plus pouvoir lancer l'affichage en asynchrone.

    ensuite, si c'est pour de l'animation rapide, peut-être que passer par directx peut donner de meilleures perf, mais, là, pour moi, c'est "terra incognita"...
    Jusqu'ici tout va bien...

  5. A voir en vidéo sur Futura
  6. #5
    mp3dux

    Re : paralléliser le remplissage d'une matrice bitmap avec GDI+ C++

    Citation Envoyé par polo974 Voir le message
    Donc, je prendrais le pb autrement:
    définir un bitmap en mémoire correspondant à la matrice (1 cellule=1 pixel), travailler direct dans le bitmap et une fois calculé, balancer le bitmap à l'écran d'un coup d'un seul avec zoom si besoin pour les petites matrices.
    ...
    c'est exactement ce que je fais,

    je ne dessine pas directement sur l'écran, mais je crée une bitmap , de meme taille que l'écran. et lorsque tout est dessiné je balance d'un coup comme tu le dis sur l'écran.

    En gros avec GDI+ je pourrai pas faire mieux c'est ça ?

    pour le double buffer j'aurais le même problème , puisque GDI plus ne peut pas dessiner en même temps 2 bitmap en arrière plan.
    Si nous faisions tout ce que nous sommes capables de faire, nous en serions abasourdis. T.E

  7. #6
    mp3dux

    Re : paralléliser le remplissage d'une matrice bitmap avec GDI+ C++

    salut,

    je reviens à la charge pour vous dire que j'ai laissé tomber GDI+ pour direct2D. En effet j'avais atteint les limites

    de GDI+. j'ai donc refait la partie graphique en direct2d, ce qui en l’occurrence me fait profiter de l'accélération matérielle et de l'anti alliasing

    gérée par la carte graphique.

    ci dessous 10 000 cellules, vous pouvez observer l'anti allising introduite par direct2d par rapport à mon premier post où tout est bien carré.

    Ici les cellules sont un peu comme arrondies et les bords lissés
    1000.PNG

    ci dessous j'ai 1 million de cellules et c'est assez fluide. j'ai aussi optimisé le code.

    -Au lieu de dessiner les cellules blanches pour les vivantes et noires pour les mortes, je projette un fond noir et je dessine que le quadrillage et les cellules vivantes...

    voilà si ça peut servir...

    oneMillion.jpg
    Dernière modification par mp3dux ; 10/10/2012 à 16h53.
    Si nous faisions tout ce que nous sommes capables de faire, nous en serions abasourdis. T.E

Discussions similaires

  1. "Image" d'une matrice avec mathematica
    Par invite2016c00b dans le forum Logiciel - Software - Open Source
    Réponses: 0
    Dernier message: 21/06/2012, 18h48
  2. Calcul de l'inverse d'une matrice avec la méthode de Newton
    Par invite35e5cb22 dans le forum Mathématiques du supérieur
    Réponses: 2
    Dernier message: 30/05/2012, 23h11
  3. Trouver matrice semblable avec matrice de passage
    Par ichigo01 dans le forum Mathématiques du supérieur
    Réponses: 1
    Dernier message: 25/08/2010, 07h57
  4. Réponses: 1
    Dernier message: 16/09/2009, 20h37
  5. Winword et GDI.exe
    Par invite333943ff dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 13/10/2004, 13h43