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

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

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

Message par djulio74 » 03 Sep 2018 10:22

oui, j'avais bien compris le fonctionnement. Faut je fasse d'avantage de test.
le soucis en fait c'est que pour chaque itération, j'ajoute un point par triangle, et vérifie les triangles voisins, hors le triangle 12 par exemple, peut avoir comme voisin le 11, le 100120 , le 5860259.
ou je pourrait utiliser les threads, c'est pour l'élévation, mais elle ne me prend déjà que 0.3sec, le propagation des biomes qui prend 0.5s. ça m’intéresserait pour les gameobject, 2 a 3 secondes.. mais voila... lol.

en fait a la fin faudrait un threads pour chaque zone, stoker chaque array de vertex, tri..etc, et après les threads, dans le main threads, instancier mes gameobject.

pour la version de unity, a l'époque j'avais tenté le portage vers le 5.0, mais j'avais plein de scripts avec plein d'erreur après. Ça m'avais un peu freiné j'avoue.

edit :
petite question, quand je lance un Threads avec

Code : Tout sélectionner

var thread = new Thread (MyFonction);
thread.Start();
il faut obligatoirement areter le threads apres la fin de la fonction ou une fois le threads arriver a la fin de la fonction il se clos tout seul?

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

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

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

Message par Alesk » 03 Sep 2018 10:42

Houla ! ça fait un long moment que je n'y ai pas retouché, je ne me souviens plus :p
Je vais fouiller dans mes archives et je te dis ça vite.

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

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

Message par Liven » 03 Sep 2018 11:11

Très intéressant tout ça.

Dommage que tu soit resté à unity 4 et java script car ça commence à sérieusement dater.

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

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

Message par Alesk » 03 Sep 2018 16:31

Hop !

J'ai recodé un petit bench d'exemple. Si tu as des questions...
J'utilise ici la classe ThreadPool, qui gère automatiquement l'instanciation des threads, c'est plus pratique.

Tu as juste à coller ce script sur un gameobject et lancer l'exécution pour voir les résultats dans la console.


Code : Tout sélectionner

using System;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

public class ThreadsTest : MonoBehaviour {


    // ce struct sert à mémoriser la plage de début et de fin assignée à chaque thred
    public struct ThreadRange {
        public int start;
        public int end;

        public ThreadRange(int start , int end) {
            this.start = start;
            this.end = end;
        }
    }

    

    // liste des ranges, un poru chaque thread
    private ThreadRange[] threadRanges;

    // liste des events d'état de chaque thread
    private ManualResetEvent[] doneEvents;

    // nombre de coeurs du système
    private int systemCoresCount = 1;


    // struct servant au test
    public struct DataContainer
    {
        public int index;
        public Vector3 position;
    }

    // tableau de test
    private DataContainer[] dataArray;


    void Start () {

        // récupération du nombre de coeurs du cpu
        systemCoresCount = SystemInfo.processorCount;

        // initialisation des events d'états et des ranges
        doneEvents = new ManualResetEvent[systemCoresCount];
        threadRanges = new ThreadRange[systemCoresCount];

        for (int i = 0; i < systemCoresCount; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            threadRanges[i] = new ThreadRange(i, i+1);
        }

        // tableau de stockage des durées d'exécution dans tous les cas de test ( de 1 à n threads)
        float[] timings = new float[systemCoresCount];

        // le test sera répété 50 fois afin de faire une moyenne des temps d'exécution
        int loops = 50;

        for(int l = 0; l < loops; l++)
        {
            // on lance plusieurs fois le test, en utilisant un coeur de plus à chaque fois
            for (int c = 1; c <= systemCoresCount; c++)
            {
                float now = Time.realtimeSinceStartup;

                // appel de la fonction de test en lui spécifiant le nombre de coeurs à utiliser
                Test(c);

                timings[c - 1] += Time.realtimeSinceStartup - now;
            }
        }
        
        // affichage des résultats
        for(int i = 0; i < systemCoresCount; i++)
        {
            timings[i] /= loops;
            Debug.Log("core * " + (i + 1) + " = " + (timings[i] * 1000).ToString("f3") + " ms\n");
        }
        
    }

    //
	void Test (int cores = 1) {

        // on fait un test sur un gros tableau...
        int total = 100000;
        dataArray = new DataContainer[total];

        // on déclare comme validés tous les events d'états de tous les threads, comme ça on est sûr qu'il n'en manquera pas un ensuite
        for (int i = 0; i < systemCoresCount; i++)
        {
            doneEvents[i].Set();
        }

        // on lance autant de threads que spécifiés
        for (int i = 0; i < cores; i++)
        {
            // l'event d'etat de ce thread doit marquer qu'il est en attente
            doneEvents[i].Reset();

            // mise à jour de la plage d'index qui seront traités par ce thread
            UpdateRange(i, cores, total);

            // démarrage du thread
            System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.Action), i);
        }
        
        // attente que tous les events soient validés
        WaitHandle.WaitAll(doneEvents);
        
    }

    // mise à jour de la plage d'index pour un thread donné
    void UpdateRange(int coreIndex , int coresCount , int totalToSplit)
    {
        int stepCount = Mathf.FloorToInt((float)totalToSplit / coresCount);

        threadRanges[coreIndex].start = stepCount * coreIndex;

        if(coreIndex == coresCount - 1)
        {
            // comme il peut il y avoir des erreurs d'arrondi sur stepCount, on force la valeur finale pour le dernier thread
            threadRanges[coreIndex].end = totalToSplit;
        }
        else
        {
            threadRanges[coreIndex].end = threadRanges[coreIndex].start + stepCount;
        }
    }

    // Fonction exécuté dans chaque thread
    // Attention ! la moindre erreur ce produisant dans cette fonction bloquera unity sans rien afficher !
    // il vaut mieux bien faire attention et totu sauver avant d'y accéder
    // c'est ici qu'on ne peux plus utiliser les fonction de UnityEngine qui ne sont pas threadsafe

    void Action(System.Object stateInfo) {

        // ici je passe juste l'index du core dans la variable stateInfo
        // là c'est un int, mais ça pourrait être n'import quoi d'autre, y compris un struct ou une classe
        // quoiqu'il en soit il faut que ça soit quelque chose qui contienne quelque part l'index du core, car on en a besoin ensuite
        int coreIndex = (int)stateInfo;
        
        // boucle sur le tableau de données, dans le range liée que coreIndex

        //Debug.Log("Run thread "+coreIndex+" from "+ threadRanges[coreIndex].start+" to "+ (threadRanges[coreIndex].end-1));
        for(int i = threadRanges[coreIndex].start , c = threadRanges[coreIndex].end; i < c ; i++)
        {
            dataArray[i].index = i;
            dataArray[i].position = Vector3.up * Mathf.Cos(1593265.654f);
        }
        //Debug.Log("Thread " + coreIndex+" finished");

        // le thread a terminé son job, on peut indiquer que l'event est validé
        doneEvents[coreIndex].Set();
    }
}


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

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

Message par djulio74 » 03 Sep 2018 18:30

Merci beaucoup l'ami. Je vais étudier ça de près. ;) :super:
j'ai pu faire quelques tests de mon coté, mais rien de bien concluant, a creuser encore.

J'ai fait un petit test de vidéo de maniement de la voiture :
https://youtu.be/NH1_cn_1a8M

ça faisait un bon moment j'avais pas ressorti le volant, lol. ah et pour info, j'ai pas encore fait le pédalier qui vas avec le volant, alors manette posée au sol, et accélérateur et frein avec un joystik commandé par mon gros orteils! :hehe: :hehe:

edit :
https://youtu.be/eUfQY2jgmH8
Dernière édition par djulio74 le 03 Sep 2018 18:54, édité 1 fois.

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

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

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

Message par Alesk » 03 Sep 2018 18:35

Cool !

Et avec des tremplins ça donne quoi ? :mrgreen:

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

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

Message par djulio74 » 03 Sep 2018 18:54

je ferais a l'ocaz une vidéo avec une config de la voiture, comment dire.. fun! ^^

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

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

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

Message par djulio74 » 03 Sep 2018 20:30

Bon, j'ai étudié un peu la question des threads.. je capte pas trop mal . mais quelques questions si ça te dérange pas.

- quand tu defini la fonction

Code : Tout sélectionner

 void Test (int cores = 1)
avec un peu avant

Code : Tout sélectionner

// appel de la fonction de test en lui spécifiant le nombre de coeurs à utiliser
                Test(c);
pourquoi "int cores = 1"? c'est nécessaire vu qu'il est censé correspondre a "c" dans "test(c)"?

- tu defini:

Code : Tout sélectionner

 public struct ThreadRange {
        public int start;
        public int end;

        public ThreadRange(int start , int end) {
            this.start = start;
            this.end = end;
        }
    }
pourrait on remplacer ça par un simple Vector2[], qui remplacerait start et end par x et y? et dans void start avoir

Code : Tout sélectionner

threadRanges = new Vector2[systemCoresCount];
- et enfin, quand tu defini "Action", le System.Object fais bien référence au "i" de "System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.Action), i);" ?


Désolé si les questions paraissent basique, mais pas vraiment l'habitude du C#.. :rouge:
Encore merci!! :super:

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

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

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

Message par Alesk » 03 Sep 2018 20:52

djulio74 a écrit :
03 Sep 2018 20:30
Bon, j'ai étudié un peu la question des threads.. je capte pas trop mal . mais quelques questions si ça te dérange pas.

- quand tu defini la fonction

Code : Tout sélectionner

 void Test (int cores = 1)
avec un peu avant

Code : Tout sélectionner

// appel de la fonction de test en lui spécifiant le nombre de coeurs à utiliser
                Test(c);
pourquoi "int cores = 1"? c'est nécessaire vu qu'il est censé correspondre a "c" dans "test(c)"?
C'est juste pour donner une valeur par défaut si jamais on ne spécifie rien à Test(), mais dans le cas présent, ça ne sert effectivement pas, c'est juste une habitude que j'ai ;)


djulio74 a écrit :
03 Sep 2018 20:30
- tu defini:

Code : Tout sélectionner

 public struct ThreadRange {
        public int start;
        public int end;

        public ThreadRange(int start , int end) {
            this.start = start;
            this.end = end;
        }
    }
pourrait on remplacer ça par un simple Vector2[], qui remplacerait start et end par x et y? et dans void start avoir

Code : Tout sélectionner

threadRanges = new Vector2[systemCoresCount];
Oui on pourrait tout à fait remplacer par un Vector2, mais comme là on bosse avec des nombres entiers, c'est plus propre de passer par un struct customisé (note: en C#, un Vector2 est aussi un struct, mais qui contient des float)
Car ensuite, si tu veux assigner les valeurs x et y à des int, il faudra faire un cast des variables... c'est "pas propre".
ça ressemblerait à ça :

Code : Tout sélectionner

int start = (int)threadRanges[n].x;
int end = (int)threadRanges[n].y; 
Je te recommande donc de garder la logique du struct personnalisé ;)


djulio74 a écrit :
03 Sep 2018 20:30
- et enfin, quand tu defini "Action", le System.Object fais bien référence au "i" de "System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.Action), i);" ?
Oui :)

Dans ce second paramètre, tu peux coller ce que tu veux comme variable, faut juste bien la recaster dans le bon type à l'arrivée.

Si tu as d'autres question... Je suis là ;)

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

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

Message par djulio74 » 04 Sep 2018 07:02

franchement, super cool de ta part, bonne explication! la preuve je pense avoir bien tout compris! :super:

j'ai de quoi bien m’occuper à essayer de mettre en place ça dans mon script existant, si besoin je sais a quelle porte toquer ::d

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Répondre

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