Soyez le premier à donner votre avis sur cette source.
Vue 12 758 fois - Téléchargée 1 394 fois
//----------------------- // Prend le tampon pour appliquer les règles de développement, Paramètre : l'indice du thread //----------------------- static private void Génération(object Numéro) { //Détermine sur quelle partie du buffer on travail int NuméroThread = (int)Numéro; int CellulesTotales = Programme.Fenetre.Hauteur * Programme.Fenetre.Largeur; int NombreDeCellules = CellulesTotales / Programme.Threads; int OffsetDépart = NuméroThread * NombreDeCellules; int TailleLigne = Programme.Fenetre.Largeur; byte[] Tampon = Programme.TamponModèle; //Remplissage for (int Indice = 0; Indice < NombreDeCellules; Indice++) { //Offset des cellules voisines int HautGauche = OffsetDépart - TailleLigne - 1; int HautMilieu = OffsetDépart - TailleLigne; int HautDroite = OffsetDépart - TailleLigne + 1; int MilieuGauche = OffsetDépart - 1; int MilieuMilieu = OffsetDépart; int MilieuDroite = OffsetDépart + 1; int BasGauche = OffsetDépart + TailleLigne - 1; int BasMilieu = OffsetDépart + TailleLigne; int BasDroite = OffsetDépart + TailleLigne + 1; //Valeur des cellules voisines à partir du tampon modèle //Système d'élimination des bords approximatif, mais plus rapide byte CelulleHautGauche; byte CelulleHautMilieu; byte CelulleHautDroite; byte CelulleMilieuGauche; if (HautGauche > 0) { CelulleHautGauche = Tampon[HautGauche]; CelulleHautMilieu = Tampon[HautMilieu]; CelulleHautDroite = Tampon[HautDroite]; CelulleMilieuGauche = Tampon[MilieuGauche]; } else { CelulleHautGauche = 255; CelulleHautMilieu = 255; CelulleHautDroite = 255; CelulleMilieuGauche = 255; } byte CelulleMilieuMilieu = Tampon[MilieuMilieu]; byte CelulleMilieuDroite; byte CelulleBasGauche; byte CelulleBasMilieu; byte CelulleBasDroite; if (BasDroite < Programme.TamponTravail.Length) { CelulleMilieuDroite = Tampon[MilieuDroite]; CelulleBasGauche = Tampon[BasGauche]; CelulleBasMilieu = Tampon[BasMilieu]; CelulleBasDroite = Tampon[BasDroite]; } else { CelulleMilieuDroite = 255; CelulleBasGauche = 255; CelulleBasMilieu = 255; CelulleBasDroite = 255; } int Total = 0; if (CelulleHautGauche == 0) Total++; if (CelulleHautMilieu == 0) Total++; if (CelulleHautDroite == 0) Total++; if (CelulleMilieuGauche == 0) Total++; if (CelulleMilieuDroite == 0) Total++; if (CelulleBasGauche == 0) Total++; if (CelulleBasMilieu == 0) Total++; if (CelulleBasDroite == 0) Total++; //Case actuelle noire : prend la 'bonne' couleur si il y en 3 autres à coté if (CelulleMilieuMilieu != 0) { //Résultat : if (Total == 3) Programme.TamponTravail[MilieuMilieu] = 0; else Programme.TamponTravail[MilieuMilieu] = 255; } //Case actuelle pleine : reste en vie seulement si 2 ou 3 voisines else { //Résultat : if (Total == 3 || Total == 2) Programme.TamponTravail[MilieuMilieu] = 0; else Programme.TamponTravail[MilieuMilieu] = 255; } OffsetDépart++; } //Indique qu'une opération est fini lock (Programme.Verrou) { Programme.Complétion++; } }
Pour la classe Task je l'avais survolée un moment mais apparemment il s'agit juste d'un 'emballage' autour des ThreadPool, et les objets 'Task' semblent à usage unique. Je vais quand même faire un essai au cas où.
Quand à l'assembleur c'est le langage que j’utilisai (x86) avant de me mettre au C#. Ça laisse des habitudes reconnaissables on dirait ;-)
En tout cas, j'ai appris quelque chose, c'est l'essentiel.
Ca me rapelle un jeu de la vie écrit en assembleur Z80, écrit en 1986 ... j'avais touché 300F(et oui, pas de problèmes avec l'euro en ce temps là...) de la revue "Amstrad CPC"!
Concernant System.Drawing.Color, c'est assez surprenant que cela entraîne une chute des performances. System.Drawing.Color étant une structure elle devrait justement optimiser les performances du fait qu'elle ne laisse aucun déchet (pas de pointeur) et du coup, ne fait jamais intervenir le Garbage Collector.
Un petit conseil : As-tu déjà exploré les solutions du namespace System.Threading.Task ? Il fournit des méthodes pour le traitement parallèle sur plusieurs cores. Cela pourrait éventuellement accroître d'avantage les perf de ton logiciel.
Simon
Concernant ma méthode 'obèse', le contenu de cette boucle est appelé 480.000 fois toutes les 10 millisecondes ... vouloir insérer des appels de fonction ou d'interface dedans pour le seul plaisir d'avoir découpé le code reviendrait à se tirer une balle dans le pied quand on connait le coût réel d'un appel de fonction.
De même, j'ai testé l'utilisation de la classe 'Color' : l'utilisation d'accesseurs (donc de fonctions) pour récupérer les valeurs RVB rallonge de plus de 20% le temps de création total de l'image ... donc je vais rester sur ma version 'Maison'.
Concernant le CheckForIllegalCrossThreads, oui c'était nécessaire dans la mesure où l'architecture du logiciel fait qu'un seul thread à la fois accède à un élément donné de la WinForm. On s'épargne ainsi de devoir accéder à chaque label à travers des 'InvokeRequired + Delegate', qui est une approche relativement lourde.
Autre chose, désactiver CheckForIllegalCrossThreads était vraiment nécessaire ?
Simon
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.