[WIP] Simu Course réaliste + Map + Volant

Modérateur : Administrateurs Suppléants

djulio74
Messages : 432
Inscription : 19 Déc 2009 22:55
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par djulio74 » 04 Sep 2018 08:22

Et me revoilà, et oui déjà! ^^

Alors voilà, me suis occupé de convertir ton script en JS ( je sais pas malin, mais tout est en JS pour l'instant dans mon projet, pas envie de tout convertir en C# pour l'instant, je procrastine un peu, lol) et tout marche bien.
J'ai exactement les même résultats qu'en C#.
par contre une remarque :
Je possède un core 17-3820. donc un quad core, mais 8 cœur, que je peux voir dans l'onglet performance du gestionnaire de tache.

hier avant ton script, j'avais fait des test avec juste

Code : Tout sélectionner

var thread = new Thread (MyFonction);
thread.Start();
et je voyais bien dans le gestionnaire de taches les 8 cœurs à l’œuvre. Hors avec ton script( en C# comme en JS), il n'y en a qu'un sur deux qui bosse ( les seul vrai cœurs physique je pense), pourtant "SystemInfo.processorCount" renvoi bien 8.
donc dans la console, a l'affichage des moyennes, les valeurs pour les cœurs 5 à 8 sont les même que pour 1 à 4 a quelque chose près.
Une idée du pourquoi du comment? ^^
Bon même qu'avec 4 seulement, je pourrait diviser le temps de certaines fonctions par 3 ou 4. :super:

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Avatar de l’utilisateur
Alesk
Messages : 1928
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par Alesk » 04 Sep 2018 09:25

Yo !

Tu devrais vraiment te mettre au C# ! C'est vraiment pas compliqué, et vu ce que tu ponds, tu as largement les capacités de t'y faire.
Et t'auras en plus accès à plus de choses qu'en js au niveau des certaines fonctions.

Sinon, pour ce qui est de cette histoires de coeurs non exploités, je ne suis pas assez calé sur le côté hardware pour pouvoir te répondre... Mais la réponse m'intéresse !
ça vaudrait le coup de poser la question sur le forum d'unity et/ou sur stackoverflow.

Pourrais-tu pondre un petit exemple comme le mien qui regroupe les deux méthodes afin d'avoir un cas concret à présenter ?

A l'origine j'utilisais aussi les Thread comme tu le faisais dans ton exemple, mais j'avais opté pour ThreadPool car ça permet justement je garder en mémoire les instances de threads au lieu de les recréer à chaque appel (ce qui permet de gratter encore quelques perfs)

EDIT : En fouillant un peu, j'ai trouvé ça :
https://stackoverflow.com/questions/230 ... threadpool

ça n'explique pas vraiment pourquoi tous tes coeurs ne sont pas utilisés, par contre ça indique que dans ton cas il vaudrait mieux utiliser directement la classe Thread (plus efficace sur les processus "longs"), que ThreadPool ;)

EDIT2 : Hooooo, ça me semble bien complet ça : http://www.albahari.com/threading/
Dernière édition par Alesk le 04 Sep 2018 09:36, édité 1 fois.

djulio74
Messages : 432
Inscription : 19 Déc 2009 22:55
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par djulio74 » 04 Sep 2018 09:34

oh ça c'est un truc qui fait plaisir a lire, merci. ;-)
oui oui je sais bien que le C# est beaucoup plus complet, j'en doute pas une seconde. Je m'y met prochainement, promis! ^^

OK, je vais rajouter la façon "basique" au script, je te pose ça dans la journée. Pis ça permettra de savoir si il y a un gain d'un coté ou de l'autre.

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Avatar de l’utilisateur
Alesk
Messages : 1928
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par Alesk » 04 Sep 2018 09:37

Cool !

Relis mon message précédent au cas où tu aurais raté mes modifications, j'ai ajouté deux liens très intéressants à la fin ;)

djulio74
Messages : 432
Inscription : 19 Déc 2009 22:55
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par djulio74 » 04 Sep 2018 10:44

pas mal ces liens en effet. ;)
non justement, dans mon cas les taches sont super courte mais répétées. Je ne peux pas fractionner la génération complète en plusieurs threads parce qu'ils utiliserai tous les même list, et chacun les modifierai.
Ça me servirait plutôt dans le sens ou une fonction, appelé plusieurs millier de fois, et qui vérifie à chaque fois une condition sur plusieurs millier d'entrées d'une liste, de subdiviser en threads cette recherche.

je potasse je potasse! :-D

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

djulio74
Messages : 432
Inscription : 19 Déc 2009 22:55
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par djulio74 » 04 Sep 2018 15:43

Bon après moult essais :

- chacune de nos deux méthodes utilise TOUT les cœurs.
- dans l'ensemble ta méthode reste la plus rapide pour les threads rapide et répétè;
- ma méthode arrive à égaler la tienne pour, comme tu disais, de longue opération des threads ( division d'une tache pour une très grande list ou array);
- chacun comporte des erreur de comptage de opération effectuée ( ta méthode plus rapidement que la mienne). Peut être dû au fait que plusieurs thread essaient d'incrémenter en même temps le Count.

Mon petit code :

Code : Tout sélectionner

#pragma strict

import System.Collections.Generic;
import System;
import System.Threading;

private var threadRanges : Vector2[]; 
private var doneEvents : ManualResetEvent[];
private var systemCoresCount = 1;
private var dataArray : Vector3[];
private var thread : Thread[];

private var Count = 0;

// defini le nombre de coeur a utiliser//
var CoreToUse = 8;
// defini la taille de la list ou array a diviser par le nombre de coeur//
var Sizetotal = 100000;
//nombre d'itération de chaque opération pour faire une moyenne//
var loops = 50 ;

function Start(){
	
	systemCoresCount = SystemInfo.processorCount;		
	doneEvents = new ManualResetEvent[systemCoresCount];		
	threadRanges = new Vector2[systemCoresCount];
	thread = new Thread[systemCoresCount];
	
	for (var i = 0; i < systemCoresCount; i++){	
		doneEvents[i] = new ManualResetEvent(false);
		threadRanges[i] = new Vector2(i, i+1);
	}
}

function Update(){
	
	// ajoute des limites aux donnée de l'inspector//
	CoreToUse = Mathf.Clamp(CoreToUse ,1, systemCoresCount);
	Sizetotal = Mathf.Clamp(Sizetotal,500, 10000000);
	loops = Mathf.Clamp(loops,1, 300);
	
	// Lance la methode "ALESK" //
	if( Input.GetKeyDown("a")){
		Count = 0;
		Launch(CoreToUse);
	}
		
	// lance la methode "DJULIO" //
	if( Input.GetKeyDown("d")){
		Count = 0;
		Launch1(CoreToUse);
	}
}

function UpdateRange(coreIndex :int , coresCount : int , totalToSplit : int){

	var stepCount = Mathf.FloorToInt(totalToSplit / coresCount);
	threadRanges[coreIndex].x = stepCount * coreIndex;

	if(coreIndex == coresCount - 1){
		threadRanges[coreIndex].y = totalToSplit;
	}
	else
	{
		threadRanges[coreIndex].y = threadRanges[coreIndex].x + stepCount;
	}
}

// ============================== METHODE ALESK ==============================//

function Launch (C : int) {

	var c = C;
	var timings = 0.0;
		
	for( var l = 0; l < loops; l++){	
		
		var now = Time.realtimeSinceStartup;
		Test(c);
		timings += Time.realtimeSinceStartup - now;	
	}
// Affiche une erreur si tout les threads ne sont pas arrivé au bout//
	if( Count != (loops * c) ){
		Debug.Log( "Count missing : " + (loops * c- Count)); 
	}
	timings /= loops;
	Debug.Log("ALESK - core * " + (c ) + " = " + (timings * 1000).ToString("f3") + " ms\n");    
}

function Test (cores : int) {
	
	dataArray = new Vector3[Sizetotal];

	for (var i = 0; i < systemCoresCount; i++){
		doneEvents[i].Set();
	}

	for ( i = 0; i < cores; i++){

		doneEvents[i].Reset();
		UpdateRange(i, cores, Sizetotal);
		System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.Action), i);
	}
	WaitHandle.WaitAll(doneEvents);
        
}



function Action( stateInfo : int) {

	var coreIndex = stateInfo;
	for(var i = threadRanges[coreIndex].x ; i < threadRanges[coreIndex].y ; i++){
		dataArray[i] = Vector3.up * Mathf.Cos(1593265.654f);
	}
	Count +=1;
	doneEvents[coreIndex].Set();
	
}

// ============================== METHODE DJULIO ==============================//

function Launch1 (C : int) {
	
	var c = C;
	var timings = 0.0;
			
	for( var l = 0; l < loops; l++){			
		var now = Time.realtimeSinceStartup;                
		Test1(c);	              
		timings += Time.realtimeSinceStartup - now;
	
	}
// Affiche une erreur si tout les threads ne sont pas arrivé au bout//
	if( Count != (loops * c) ){
		Debug.Log( "Count missing : " + (loops * c- Count)); 
	}        
	timings /= loops;
	Debug.Log("DJULIO - core * " + (c) + " = " + (timings * 1000).ToString("f3") + " ms\n");   
       
}

function Test1 (cores : int) {
	
	dataArray = new Vector3[Sizetotal];
	
	for ( var i = 0; i < cores; i++){	

		UpdateRange(i, cores, Sizetotal);

		var I = i;
		thread[i] = new Thread (Action1);
		thread[i].Start(I);
	}
	
	for ( i = 0 ; i < cores ; i++){
		thread[i].Join();
	
	}
}

function Action1( stateInfo : int) {

	var coreIndex = stateInfo;

	for(var i = threadRanges[coreIndex].x ; i < threadRanges[coreIndex].y ; i++){
		dataArray[i] = Vector3.up * Mathf.Cos(1593265.654f);
	}
	
	Count +=1;

}
En mode "Play", dans l'inspector changer le nombre de cœur a utiliser, d'itération, de longueur d'array, touche "a" du clavier pour ta methode, touche "d" pour la mienne.

je sais pas pourquoi, dans ton C#, on dirait c’était le fait de faire le test pour chaque nombre de cœur a utiliser qui faisait qu'ils n’étaient justement pas tous utilisé. ou me suis planté quelque part. lol

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Avatar de l’utilisateur
ZJP
Messages : 5686
Inscription : 15 Déc 2009 06:00

Re: [WIP] Simu Course réaliste + Map + Volant

Message par ZJP » 04 Sep 2018 18:31

djulio74 a écrit :
04 Sep 2018 15:43
...
- chacun comporte des erreur de comptage de opération effectuée ( ta méthode plus rapidement que la mienne). Peut être dû au fait que plusieurs thread essaient d'incrémenter en même temps le Count.
...
Oui, pas évident.

D'où la solution sur laquelle j'avais travaillé....
Pour triompher, le mal n’a besoin que de l’inaction des gens de bien.Edmund Burke (1729-1797)

Avatar de l’utilisateur
Alesk
Messages : 1928
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par Alesk » 04 Sep 2018 18:43

ha ben voui mais non... Moi j'utilise la dernière version d'Unity... qui ne supporte plus l'unityscript :gene:

Faut passer au C# ! Tu te feras plein d'amis :mrgreen:
djulio74 a écrit :
04 Sep 2018 15:43
- chacun comporte des erreur de comptage de opération effectuée ( ta méthode plus rapidement que la mienne). Peut être dû au fait que plusieurs thread essaient d'incrémenter en même temps le Count.
Bah oui mais non, il ne faut PAS que les threads accèdent tous à une même variable, ils doivent impérativement ne toucher qu'à des variables qui leurs sont destinées spécifiquement.
D'où mon découpage de tableaux en tronçons, pour que chaque thread ne touche qu'à sa section, sans jamais interférer avec les autres.

Avatar de l’utilisateur
Liven
Messages : 267
Inscription : 30 Nov 2017 01:48

Re: [WIP] Simu Course réaliste + Map + Volant

Message par Liven » 04 Sep 2018 18:54

Je rejoint Alesk et t'encourage vivement à passer au C# (et à une version plus récente de Unity par la même occasion) car vu ce que tu fais, je trouve que c'est du gâchis de rester sur des tech aussi vieilles.

Avatar de l’utilisateur
Alesk
Messages : 1928
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [WIP] Simu Course réaliste + Map + Volant

Message par Alesk » 04 Sep 2018 19:02

Après relecture de ton code, j'ai compris pourquoi tu as un problème avec ta variable Count : elle n'est effectivement pas incrémentée au bon endroit pour ce qui concerne mon exemple de code.
Mais elle est surtout inutile !

Aucun thread ne peut être manquant.

La fonction WaitHandle.WaitAll(doneEvents); va bloquer le thread principal tant que tous les éléments du tableau doneEvents ne seront pas validés.
Donc si jamais un thread plante, Unity va se figer à cet endroit du code car ça va attendre à l'infini le thread planté.

Donc, à la ligne d'après WaitHandle.WaitAll(doneEvents); , tu es sûr que tous les threads invoqués avant ont terminés leur exécution correctement.

Répondre

Revenir vers « Vos créations, jeux, démos... »