IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Construction d'une image pixel par pixel en multi-threads


Sujet :

avec Java

  1. #1
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut Construction d'une image pixel par pixel en multi-threads
    Bonjour à vous,

    J'ai récemment créé un petit moteur de rendu de scène 3D. De base, il n'utilisait pas de threads supplémentaires.

    Le traitement (la génération de l'image) prend ~2.5s. Je me suis donc dit que je pourrais essayer d'accélérer un peu tout ça en multi-threads (sur un core i7 920 d0 (4 cores physiques, 4 logiques)).

    Le résultat: le programme met ~4.3s à l'exécution, mon implentation de threads l'a beaucoup ralentie. Je ne comprends pas bien pourquoi.

    L'algorithme sans ajout de threads:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for (int i = 0; i < hauteurImage; i++) {
         for (int j = 0; j < largeurImage; j++) {
            //calcul de la couleur du pixel
            //traitement de la couleur du pixel (pour le out of gamma)
            //affichage du pixel
            fenetre.getGraphics.setColor(couleurCalculee);
            fenetre.getGraphics.fillRect(ligne, colonne, 1, 1);
        }
    }
    Et en multi-threads:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    //déclaration de x threads, où x = Runtime.getRuntime().availableProcessors();
    for (int i = 0; i < hauteurImage; i++) {
         for (int j = 0; j < largeurImage; j++) {
            Thread truc = listeThreads.get(j%x); //thread correspondant au pixel en cours
            truc.join(); //attendre le traitement précédent du thread
            truc.start(); //calcul du pixel puis affichage de celui-ci, de la même méthode qu'en simple thread
        }
    }
    J'ai aussi essayé en créant un thread temporaire par calcul de pixel, mais les résultats sont les mêmes.

    Au final, les threads calculent un thread sur x, où x est le nombre de coeurs disponibles (ici 8, testé avec 4 aussi, mêmes résultats).

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    ton join() fait que à chaque itération(), tu attends que ton thread soit terminé, donc en réalité tu n'est pas en multithread.

    tu devrais essayer de gérer plutôt ça par un système de pool de thread : à chaque itération tu empile un ordre de calcul de point, ton pool étant chargé de paralléliser les traitement.

    regarde l'api java.util.concurent

    par exemple...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public class DessineImage {
     
      public final Fenetre fenetre;
     
      public DessineImage(int hauteurImage, int largeurImage, Fenetre fenetre) {
        this.fenetre=fenetre;
     
        ExecutorService service = Executors.newFixedThreadPool(10/*nombre de threads*/);
     
        for (int i = 0; i < hauteurImage; i++) {
          for (int j = 0; j < largeurImage; j++) {
          	service.execute(new CalculPoint(j,i));
          }
        }
     
        service.shutdown();
      }
     
      public class CalculPoint implements Runnable {
     
        private final int colonne;
        private final int ligne;
     
        public CalculPoint(int colonne, int ligne) {
          this.colonne=colonne;
          this.ligne=ligne;
        }
     
        @Override
        public void run() {
            //calcul de la couleur du pixel
            //traitement de la couleur du pixel (pour le out of gamma)
            //affichage du pixel
            fenetre.getGraphics().setColor(couleurCalculee);
            fenetre.getGraphics().fillRect(ligne, colonne, 1, 1);
     
        }
      }
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Bonsoir et merci de ta réponse.

    eclesia m'a conseillé d'utiliser ceci aussi. Je l'ai donc implanté, l'exécution prend maintenant ~12 secondes. :/ Il m'a conseillé de regarder le temps d'exécution des méthodes, ce que je vais faire.

    Concernant le join, en fait j'avais plusieurs threads, donc j'attendais seulement le thread qui était sensé calculer le pixel (je fais un .get sur une liste de threads précédemment déclarés).

  4. #4
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Je viens aux nouvelles, j'avais laissé des centaines d'exécutions de System.out.println, d'où le temps d'exécution. Au final, le temps d'exécution passe à ~2.5s.

    Soit environ le même temps qu'en simple thread. Les changements dans Graphics puis son affichage semble être le "souci" étant donné qu'une instruction seulement ne peut être faite en même temps. Bref, il va à priori falloir queje me débarasse de graphics.

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    il y a plusieurs choses à considérer :

    - déjà les threads java ne sont pas des threads système mais des threads simulés dans la jvm : donc il y a un temps de partage.
    tu peux éventuellement modifier la fabrique de thread pour modifier la priorité d'exécution de tes threads

    - toute introduction de méthodes intermédiares introduit des temps de traitement en particulier pour la gestion de la pile

    - l'instanciation des Runnable introduit un temps non négligable : on peut résoudre ça par un pool par exemple

    - après il faut regarder comment est implémenté ton setColor et ton fillRect
    tu peux éventuellement dessiner ton point par manipulation d'octet probablement plus rapide que les méthodes de dessin de la classe Graphics2D


    - il faut mettre en opposition le temps de traitement unitaire de tes pixels et le temps introduit par l'introduction de thread : peut être que faire un thread par ligne serait plus efficace, ou découper ton image en bloc
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    pour les threads simulés, je me suis mal exprimé, les threads java sont mappés sur des threads natifs, mais ce sont pas des threads natifs, dans le sens ou il y a une surcouche de gestion interne qui introduit nécessairement un temps des gestion. maintenant il est peut probablement de gagner tant que ça en implémentant des threads complètement natif, sauf en introduisant la gestion de l'affinité de manière à optimiser la répartition sur les différents processeurs
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Merci pour toutes ses informations, ça me sera très utile.

    Je vais faire des tests, tenter des blocs de pixel par thread, l'instanciation doit prendre un certain temps en effet, pour une image de 400x400 ça me faisait 160 000 instanciations d'objet runnable.

    Edit: par bloque de pixel ça reste au même temps d'exécution, je vais voir pour essayer de changer l'affichage, peut-être stocker l'image entière et l'afficher d'un coup au lieu d'appeler x fois fillRect & setColor, et si ça ne fonctionne pas mieux, voir pour trouver un autre moyen d'afficher l'image

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par garheb Voir le message
    Merci pour toutes ses informations, ça me sera très utile.

    Je vais faire des tests, tenter des blocs de pixel par thread, l'instanciation doit prendre un certain temps en effet, pour une image de 400x400 ça me faisait 160 000 instanciations d'objet runnable.
    ça peut compter, mais bon 160000 instanciations,ça doit prendre peanuts (sur mon vieux pc pourri hyper lent (atom sous xp c'est pour dire), je viens de tester : 15ms) par rapport à 2,5s, mais bon, additionnées des ms, ça peut compter,

    essayer de voir si tu peux pas optimiser tes calculs aussi (factoriser par exemple, précalculer, etc)
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #9
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Ok, donc utiliser des * inverse au lieu de /, calculer des variables constantes au départ, et les réutiliser.

    Je vais faire ça. (Ca va prendre du temps, y'a beaucoup de calculs )

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par garheb Voir le message
    Ok, donc utiliser des * inverse au lieu de /, calculer des variables constantes au départ, et les réutiliser.

    Je vais faire ça. (Ca va prendre du temps, y'a beaucoup de calculs )
    oui ou faires des décalages au lieu de multiplications,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i=0;i<10000000;i++) {
    			int a=2;
    			a=a+a;
    }
    47ms

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i=0;i<10000000;i++) {
    			int a=2;
    			a*=2;
    }
    47ms


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i=0;i<10000000;i++) {
    			int a=2;
    			a<<=1;
    }
    32ms

    pour les multiplications à la place des divisions ça dépend de tes opérandes à mon avis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i=0;i<10000000;i++) {
    			int a=2;
    			a/=2;
    }
    32ms

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i=0;i<10000000;i++) {
    			int a=2;
    			a*=0.5;
    }
    125ms !

    mais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int b=2;
    		for(int i=0;i<10000000;i++) {
    			int a=2;
    			a/=b;
    }
    454 ms !

    alors que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    final int b=2;
    		for(int i=0;i<10000000;i++) {
    			int a=2;
    			a/=b;
    }
    160ms !
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    En effet, je ne savais pas que ça changeait tant la donne de mettre en final ce qui doit l'être. Merci pour ces exemples, très instructif.

  12. #12
    Membre éprouvé

    Homme Profil pro
    Ingénieur logiciel embarqué
    Inscrit en
    Juillet 2002
    Messages
    386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur logiciel embarqué
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2002
    Messages : 386
    Points : 1 164
    Points
    1 164
    Par défaut
    L'api graphique java2D (fillRect, fillPolygon &co) peut paraître capricieuse car elle est accéléré par le matériel.

    De plus fillRect est une méthode complexe (il se passe plein de chose derrière), cela se vois très vite lors d'un profilling.

    Si tu veu travailler sur ton image au niveau des pixel tu peu utiliser un tableau:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    BufferedImage buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    int[] data = ((DataBufferInt) buffer .getRaster().getDataBuffer()).getData();
     
    //ici tu peut modifier les pixels dans data, buffer sera mis a jour en fonction
    ...
    graphics.drawImage(buffer, 0, 0, null)
    Déjà ca devrai booster tes perf. Tu peu avoir besoin de passer par un buffer intermédiaire (de mémoire le fait d’accéder directement aux pixels d'une Buffered Image peu désactiver certaines accélérations).
    Note que je suis curieux de voir tes temps après ces modifs.

    Pour la partie multithread, créé un thread par pixel, ca n'a pas de sens, a moins que ton pixel demande une méchante quantité de calcul, un thread c'est puissant mais "complex" pour le processeur. En gros l'idéal est de decouper ton image en 8 ou 16 sous images chacunes traitées dans un thread. Quant tout les threads ont fini leur travail tu dessine les N images aux bonnes positions sur ton ecran pour ainis reconstruire l'image final.
    (ok c'est plus simple a dire qu'a faire )

    Si tu a du post - traitement tu peu faire une file (pipeline) ou chaque thread fait un traitement sur l'image et le passe au thread suivant. Ca peu induire un peu de latence par contre.

    En espérant avoir aidé, bonne chance !

  13. #13
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Bonjour!

    Je tombe à 1.4 secondes, en effet, une seconde de gagnée là-dessus! J'ai fait comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    BufferedImage _buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    int[] _donnees = new int[h*w];
    un setter pour remplir _donnees dans les threads puis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    _buffer.getRaster().setDataElements(0, 0, w, h, _donnees);
    _scene.getAffichage().drawImage(_buffer, 0, 0, null);
    Je me posais une question concernant les différents calculs à optimiser: est-ce une bonne chose d'arrondir les double avant une division?

    Par exemple, je manipule une valeur: 5.54165451517

    puis je fais x/=valeur

    Est-ce qu'arrondir la valeur à deux décimales (par exemple) près va accélérer tout ça? Ou au contraire, est-ce que le Math.round va ralentir le calcul?

    Edit: La mise à jour de l'image (une fois générée une fois) avec un drag & drop d'objet dans la scène est quasimment instantanée (400ms), vraiment cool. Le résultat est quasimment du temps réel lors de mouvements successifs des objets)

  14. #14
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    salut
    Citation Envoyé par garheb Voir le message
    Bonjour!

    Je tombe à 1.4 secondes
    cool
    Citation Envoyé par garheb Voir le message
    , en effet, une seconde de gagnée là-dessus! J'ai fait comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    BufferedImage _buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    int[] _donnees = new int[h*w];
    un setter pour remplir _donnees dans les threads puis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    _buffer.getRaster().setDataElements(0, 0, w, h, _donnees);
    _scene.getAffichage().drawImage(_buffer, 0, 0, null);
    Je me posais une question concernant les différents calculs à optimiser: est-ce une bonne chose d'arrondir les double avant une division?

    Par exemple, je manipule une valeur: 5.54165451517

    puis je fais x/=valeur

    Est-ce qu'arrondir la valeur à deux décimales (par exemple) près va accélérer tout ça? Ou au contraire, est-ce que le Math.round va ralentir le calcul?
    non je pense que çà fera rien : à priori les opérations en virgule flottante sont réalisées par le processeur, en un nombre de cycle qui ne dépend à priori pas de nombre de décimales

    le round ralentira forcément le traitement et l'utilisation de l'arrondi au plus tôt dans tes calculs va introduire une dérive (une erreur) qui va forcément s'amplifier au long des calculs
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  15. #15
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Merci de ces renseignements, j'ai encore des calculs à optimiser puis il faudra que je cherche d'autres pistes d'améliorations.

    Les Math.cos & sin, à utiliser tel quel ou faire sa propre fonction (ou une fonction optimisée trouvée) pour gagner encore en perfs?

    Edit: Selon l'outil de mesure des temps de traitement cpu des différentes méthodes & threads, il s'agit bien du boulot des threads qui prend le plus de temps, donc c'est bien à ce niveau qu'il faut que j'optimise, l'affichage prend ~200ms, tandis que les threads prennent ~1.3s. Et plus précisément la méthode de détection des collisions des rayons (le moteur de rendu est en ray tracing) avec les objets de la scène.

  16. #16
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par garheb Voir le message
    Merci de ces renseignements, j'ai encore des calculs à optimiser puis il faudra que je cherche d'autres pistes d'améliorations.

    Les Math.cos & sin, à utiliser tel quel ou faire sa propre fonction (ou une fonction optimisée trouvée) pour gagner encore en perfs?
    pour les cos et sin, tu peux précalculer des tables(échantillonage), mais tu perdras en précision, tout dépend de tes calculs : tu peux essayer par dichotomie de chercher la précision qui suffit pour ton calcul

    je ne sais pas trop comment sont réalisées les cos et sin de java, mais j'imagine que même si elles ne sont pas traitées par le processeur directement (ce qui m'étonnerait aujourd'hui), elle doivent utiliser les algos les plus rapides. on ne peut pas exclure qu'un mathématicien ai pondu une formule de la mort qui tue de calcul de sinus ou cosinus depuis que les fonctions utilisées par java ont été implémentées, et qui écrasent les temps de calculs des algo précédents, mais bon, y'a peu de chances à mon avis, surtout que si tu refais l'implémentation d'un algo en java tu ne sera pas aussi performance qu'un proc
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  17. #17
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    tiens j'ai trouvé ça rapidement : http://www.java-gaming.org/index.php?topic=24191.0
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  18. #18
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    Merci je vais regarder ça.

  19. #19
    Membre averti
    Inscrit en
    Juin 2011
    Messages
    258
    Détails du profil
    Informations forums :
    Inscription : Juin 2011
    Messages : 258
    Points : 334
    Points
    334
    Par défaut
    C'est appliqué, le temps d'exécution ne change pas énormément, environ 50ms mais c'est très variable (sin & cos doivent être utilisés ~1000 fois pendant une exécution).

  20. #20
    Membre éprouvé

    Homme Profil pro
    Ingénieur logiciel embarqué
    Inscrit en
    Juillet 2002
    Messages
    386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur logiciel embarqué
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2002
    Messages : 386
    Points : 1 164
    Points
    1 164
    Par défaut
    Au risque de redire la meme chose, profile ton sin et ton cos, si tu ne les appel que 1000 fois, j'imagine que ce n'est pas le point critique.

    Pour ce qui est de la perf, tout dépend de ce que tu veu atteindre.

    Historiquement tu peu faire rouler un jeu 3D dur un processeur a 100Mhz, le tout codé en C et ASMx86. Pour cela tu a 3 "secrets" :

    -Connaitre les point faibles de ton langage (tu commence a en éliminer pas mal)
    - Simplifier les calcules (lookuptable, comparer des ² plutôt que calculer une racine, ...)
    - Diminuer le nombre de calcul nécessaire (c'est l’étape ou tu va gagner gros si tu trouve comment faire,tu a des piste dans la FAQ : http://jeux.developpez.com/faq/3d/?page=culling)

    si tu veux pouvoir rendre n'importe quoi, le 3eme point est délicat et son application limité.

    PS : on veux des screens !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Import d'une image PNG par pixel
    Par LudoParis dans le forum VB.NET
    Réponses: 7
    Dernier message: 12/12/2011, 19h47
  2. Image a remplir Pixel par Pixel, Quel objet utiliser ?
    Par ZbergK dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 28/02/2007, 21h35
  3. [ImageMagick] Parcourir une image pixel par pixel
    Par kip dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 05/10/2005, 14h10
  4. [VB6] [Graphisme] Transfert d'image pixel par pixel
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 15/10/2002, 09h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo