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

Java Discussion :

Connaître les optimisations faites par la JVM


Sujet :

Java

  1. #1
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut Connaître les optimisations faites par la JVM
    Bonjour,

    y a t-il un moyen de savoir si un code java a été optimisé par/pour la JVM ?

    Voilà comment j'en suis arrivé à me poser cette question :
    Je fais actuellement du traitement d'images en 3D. Mon image est représentée par un tableau 1D.
    Je fais un même traitement suivant les trois plans possibles (XY, XZ, YZ). Le code est exactement le même pour chaque plan (voir ci-dessous), je n'ai besoin que de modifier deux variables pour traiter différents plans, mais à l'arrivée chaque traitement fait EXACTEMENT le même nombre d'opérations/comparaisons/lectures/écritures.
    Seulement, le temps de traitement d'un plan par rapport à un autre peut aller du simple au triple.

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    System.arraycopy(intbufferin, pos, intbufferout, pos, width) ;
    for (s=-1, p=pos-Param1 ; -sewidth <= s && 0 <= Param2+s ; s--, p-=Param1)
    	ArrayOperations.Maximum(intbufferin, p, intbufferout, pos, intbufferout, pos, width) ; // Simple maximum entre deux tableaux


    J'en déduis donc que le code qui traite plus rapidement un certain plan a dû recevoir une quelconque optimisation et j'aimerai savoir déterminer laquelle.


    Merci par avance...
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Attention que cela pourrait également être causé par le GC.
    Je ne sais pas si on peut voir les optimisations qui sont effectué, mais tu peux logger le passage du GC et les compilations avec les options -XX:+PrintGC -XX:+PrintCompilation.


    a++

  3. #3
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Si tu veux voir si le compilateur a optimisé ton code, il n'y a pas 36 solutions : décompiler la classe et voir si elle est identique ou pas.
    Mais après, avec le système de JIT, c'est difficile de savoir quelles autres optimisations peuvent être réalisées à l'exécution...

    Clairement, je connais pas assez les méandres des optimisations de dernières minutes à l'exécution pour voir pourquoi tu as de telles différences à l'exécution...
    Je ne suis pas mort, j'ai du travail !

  4. #4
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Attention que cela pourrait également être causé par le GC.
    Je ne sais pas si on peut voir les optimisations qui sont effectué, mais tu peux logger le passage du GC et les compilations avec les options -XX:+PrintGC -XX:+PrintCompilation.
    Merci pour ta réponse, mais c'est peu vraisemblable dans mon cas, car toutes les opérations n'utilisent pas de mémoire supplémentaire. Une fois mon volume à traité lu et le volume résultat créé, aucune mémoire supplémentaire n'est utilisée. De plus ces deux volumes ne représentent que très peu de mémoire, je ne suis même pas à 5% de la mémoire disponible.
    Citation Envoyé par eulbobo Voir le message
    Si tu veux voir si le compilateur a optimisé ton code, il n'y a pas 36 solutions : décompiler la classe et voir si elle est identique ou pas.
    Mais après, avec le système de JIT, c'est difficile de savoir quelles autres optimisations peuvent être réalisées à l'exécution...
    Merci pour l'idée. Saurais tu comment "décompiler" efficacement ?
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  5. #5
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    J'ai beaucoup utilisé JAD, mais je ne sais pas ce qu'il vaut pour les dernières versions de Java. Je sais pas s'il est compatible Java8 par exemple.

    A tenter !

    http://varaneckas.com/jad/
    Je ne suis pas mort, j'ai du travail !

  6. #6
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    merci, je vais tester.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Le compilateur optimise peu de choses. Certes ils peux retirer des assignations inutiles ou réorganiser un peu le code, mais c'est limité. Le langage java permettant la redéfinition de la plupart des méthodes, donc le compilo a peu de chance de savoir quelle méthode sera réellement utilisée. Par contre, le JIT lui dispose de beaucoup plus d'informations concrête et c'est lui qui fait toutes les optimisations. Tu peux ajouter -XX:+PrintCompilation à ta ligne de commande java pour voir ce que fait le jit. Si une des tes méthodes est beaucoup plus souvent utilisée que l'autre, elle sera compilée nativement plus vite que l'autre. Ce document pourrait te servir. http://www.oracle.com/technetwork/ar...1-2266278.html

  8. #8
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Il faut aussi prendre en compte le chargement des données dans le cache processeur ainsi que les opérations de vectorisation.
    Faire des calculs sur plusieurs cases adjacentes d'un tableau pourra être transformé par le compilateur JIT en opérations parallèles (instructions AVX, SSE, MMX...) alors que les mêmes calculs mais sur des cases non adjacentes ne pourra pas (ou sera beaucoup plus difficile pour le compilateur à) être vectorisé donc sera séquentiel donc sera plus lent sur le temps global.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  9. #9
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Merci pour vos réponses.
    Les opérations se font exactement de la même façon dans les deux cas : comparaisons de lignes, donc j'avance case par case adjacentes. La seule différence c'est qu'un coup je compare des ligne en me déplaçant horizontalement et en dans l'autre cas c'est vertical.
    Par contre je doute très fort que même si je ne fais que des opérations de comparaisons sur lignes/cases adjacentes et des copies en mémoire, tout cela soit compilé en natif. Je vais d'ailleurs comparer les performances en compilant du C (sans doute auto-vectorisé) et en l'appelant par JNI.
    D'ailleurs, y a t-il un moyen de forcer le JIT à compiler nativement ?
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    le jit compile nativement en fonction du nombre d'usage. Plus une section de code est utilisée, plus elle deviens candidate à la compilation native. Bref, c'est après N passage dans la boucle que le jit va décider de compiler nativement plutot que d'interpréter.

    Si ton parcours est différent, il peut justifier de la lenteur. si tu avance de 1 en 1 dans le tableau, c'est plus rapide que d'avancer de 1000 en 1000 car les données viennent du cache.

  11. #11
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    le jit compile nativement en fonction du nombre d'usage. Plus une section de code est utilisée, plus elle deviens candidate à la compilation native. Bref, c'est après N passage dans la boucle que le jit va décider de compiler nativement plutot que d'interpréter.
    La question intéressante est alors : "est ce que l'on peut forcer/aider le JIT à compiler nativement ?".
    Car mes traitements c'est du lourd... donc le natif serait parfait pour moi.


    Citation Envoyé par tchize_ Voir le message
    Si ton parcours est différent, il peut justifier de la lenteur. si tu avance de 1 en 1 dans le tableau, c'est plus rapide que d'avancer de 1000 en 1000 car les données viennent du cache.
    J'avance toujours de 1 par 1, car je traite ligne par ligne.
    Mais dans un cas je vais à la ligne suivante, dans l'autre à la ligne du dessus.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    -Xcomp force la compilation native de toutes les méthodes / classes dès le premier usage. Bouffe du temps en compilation jit et empêche la recompilation en fonction du profiling. Peut amener de sous optimisations
    -XX:CompileThreshold premet de préciser à partir de combien d'appel la méthode est compilée
    -Xbatch force à attendre la compilation jit de la méthode plutot de que de faire cette compilation en arrière plan
    -XX:+TieredCompilation force une première compilation rapide au premier usage de la méthode en attendant la compilation optimisée plus tard. (java 7)

  13. #13
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    -Xcomp force la compilation native de toutes les méthodes / classes dès le premier usage. Bouffe du temps en compilation jit et empêche la recompilation en fonction du profiling. Peut amener de sous optimisations
    -XX:CompileThreshold premet de préciser à partir de combien d'appel la méthode est compilée
    -Xbatch force à attendre la compilation jit de la méthode plutot de que de faire cette compilation en arrière plan
    -XX:+TieredCompilation force une première compilation rapide au premier usage de la méthode en attendant la compilation optimisée plus tard. (java 7)

    C'est exactement ce que je cherchais !!!

    Je fais du traitement d'images et tout est très gourmand en CPU. De plus, je traite un très grand nombre d'images ou de grand volumes.
    Une compilation native avant même de démarrer quoi que ce soit va juste me sauver la vie et un temps précieux !!!

    Comme je fais toujours les mêmes opérations, sans polymorphisme, je pense que je ne devrais jamais avoir de sous optimisations. Dans quel cas est ce que cela pourrait arriver ?
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  14. #14
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par dinobogan Voir le message
    Il faut aussi prendre en compte le chargement des données dans le cache processeur ainsi que les opérations de vectorisation.
    Les derniers algorithmes que j'utilise sont exactement la même chose qu'en C et ils sont auto-vectorisable. Est ce que l'on peut forcer/vérifier l'auto-vectorisation ?
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  15. #15
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    Comme je fais toujours les mêmes opérations, sans polymorphisme, je pense que je ne devrais jamais avoir de sous optimisations. Dans quel cas est ce que cela pourrait arriver ?
    Je ne connais pas les détails. Les optimisations dépendent entre autres des paramètres des méthodes, par exemple le compilo jit pourrait détecter qu'il est certaines d'être dans les limites d'un tableau (le tableau n'est pas visible à l'extérieur, les paramètres sont toujours dans les bornes connues) et décider de retirer les check de boundaries par exemple. Pour ta partie sans polymorphisme: indique le bien à la jvm et rendant les méthodes final ou private.

  16. #16
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    il est certaines d'être dans les limites d'un tableau (le tableau n'est pas visible à l'extérieur, les paramètres sont toujours dans les bornes connues) et décider de retirer les check de boundaries par exemple.
    J'aimerai vraiment être capable d'imposer cela à JIT, mais je suppose que cela n'est pas possible. Je fais du traitement d'image et cela m'aiderait vraiment car la plupart des traitements se font sur le tableau représentant l'image et sans risque de débordements.


    Citation Envoyé par tchize_ Voir le message
    Pour ta partie sans polymorphisme: indique le bien à la jvm et rendant les méthodes final ou private.
    Bonne idée, je vais modifier tout ce qu'il faut.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  17. #17
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    J'aimerai vraiment être capable d'imposer cela à JIT, mais je suppose que cela n'est pas possible. Je fais du traitement d'image et cela m'aiderait vraiment car la plupart des traitements se font sur le tableau représentant l'image et sans risque de débordements.
    Il faut le prouver à la JVM. Et pour ça il n'y a pas d'avance:

    les index d'accès au tableaux doivent être calculable statiquement. Donc pas d'appel de méthode pour calculer un index. Si l'index fait partie d'une boucle, l'index doit n'être incrémenté que par la boucle. JIT va alors analyser les limite de la boucle avant de rentrer dedans, appliquer la règle de calcul aux limites et voir si les limites ainsi calculées sont dans le range du tableau. Si c'est la cas, plus besoin de faire des check de limite dans la boucle.

    le tableau ne peut pas être modifiable dans la boucle. Autrement dit: ça c'est bon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int[] tableau = ....;
    for (.....){
       tableau[....] = maMethode(tableau[....],....);
    }
    ça c'est pas bon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    this.tableau = ....;
    for (.....){
       maMethode(....);
    }

    Et quand je vois ton code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    System.arraycopy(intbufferin, pos, intbufferout, pos, width) ;
    for (s=-1, p=pos-Param1 ; -sewidth <= s && 0 <= Param2+s ; s--, p-=Param1)
    	ArrayOperations.Maximum(intbufferin, p, intbufferout, pos, intbufferout, pos, width) ;
    J'ai du mal à voir ce qui pourrait laisser supposer quelque chose d'optimisable:

    D'où vient Param1? Il est local? Si c'est une champ de classe, ça veux dire que l'incrémentation de p n'est pas prévisible. Donc on ne peux pas optimiser cette partie.
    D'où viennent Param2 et sewidth? Il sot locaux? Si c'est une champ de classe, ça veux dire que la limite de s n'est pas prévisible. Donc on ne peux pas optimiser cette partie.
    intbufferin et intbufferout sont locaux à la méthode? Si pas, ça veux dire qu'on ne peux pas sortir un quelconque boundary check en dehors de la boucle, car ArrayOperations.Maximum pourrait changer ces tableaux.
    Même avec tout local, j'ai du mal à voir en quoi le jit peux supposer qu'il peux faire les opérations en //. ArrayOperations.Maximum c'est une blackbox pour lui, l'opération 2 peux très bien être dépendante du résultat de l'opération 1. Si ArrayOperations.Maximum est static ou final et que le code est petit, le jit peux l'inliner et du coup l'optimisation de la boucle peux commencer. Pourquoi ne pas transférer la boucle dans ArrayOperations.Maximum directement?


    Tu as trois choses au niveau de l'optimisation qui expliquent la différence c / java:

    c n'as aucune notion de polymorphisme, ce qui permet de connaitre le chemin à la compilation. jit doit faire de l'analyse dynamique, faire des supposition et être beaucoup plus prudent pour ne pas briser le language
    c n'effectue aucun test de débordement. java garanti qu'on ne débordera jamais
    la compilation c vise une architecture particulière, java est crossplatforme, il faut donc penser tes optimisations en tenant compte des différentes cibles.

  18. #18
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    cette discussion pourrait aussi t'intéresser.

    http://stackoverflow.com/questions/1...-or-other-adva

  19. #19
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Et quand je vois ton code:

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    System.arraycopy(intbufferin, pos, intbufferout, pos, width) ;
    for (s=-1, p=pos-Param1 ; -sewidth <= s && 0 <= Param2+s ; s--, p-=Param1)
    	ArrayOperations.Maximum(intbufferin, p, intbufferout, pos, intbufferout, pos, width) ;
    J'ai du mal à voir ce qui pourrait laisser supposer quelque chose d'optimisable:

    D'où vient Param1? Il est local? Si c'est une champ de classe, ça veux dire que l'incrémentation de p n'est pas prévisible. Donc on ne peux pas optimiser cette partie.
    D'où viennent Param2 et sewidth? Il sot locaux? Si c'est une champ de classe, ça veux dire que la limite de s n'est pas prévisible. Donc on ne peux pas optimiser cette partie.
    intbufferin et intbufferout sont locaux à la méthode? Si pas, ça veux dire qu'on ne peux pas sortir un quelconque boundary check en dehors de la boucle, car ArrayOperations.Maximum pourrait changer ces tableaux.
    Même avec tout local, j'ai du mal à voir en quoi le jit peux supposer qu'il peux faire les opérations en //. ArrayOperations.Maximum c'est une blackbox pour lui, l'opération 2 peux très bien être dépendante du résultat de l'opération 1. Si ArrayOperations.Maximum est static ou final et que le code est petit, le jit peux l'inliner et du coup l'optimisation de la boucle peux commencer. Pourquoi ne pas transférer la boucle dans ArrayOperations.Maximum directement?
    Voici la méthode :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    public static void Maximum(int[] array1, int start1, int[] array2, int start2, int[] result, int start, int length) ;
    Elle va devenir final... je suis en train de modifier toutes les méthodes identiques. Ce sont des petites méthodes static aussi simples qu'utiles, ne comportant qu'une seule bouche avec un seul test. C'est donc la parfaite candidate pour devenir final.

    Pour les autres, ce sont des paramètres dépendant de mon image. Voici une idée de ce que je fais :
    Code java : 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
     
    public class maclass
    {
    private int param1, param2, sewidth ;
    private int width, height ;
     
    public void setParameters(BufferedImage image, int sewidth) // Je récupère les paramètre dont j'aurai besoin plus tard.
    	{
    	param1 = image.getParam1() ;
    	param2 = image.getParam2() ;
    	this.sewidth = sewidth ;
    	this.width = image.getWidth() ;
    	this.height = image.getHeight() ;
    	}
     
    public void process(BufferedImage image, BufferedImage result) // Traitements de mon image en fonction des paramètres récupérés.
    	{
    	int[] inbufferin = image.getDataBufferInt() ; // Version simplifiée...
    	int[] inbufferout = result.getDataBufferInt() ; // Version simplifiée...
     
    	int y, pos ;
    	for (y=pos=0 ; y < height ; y++, pos+=width) // Me permet de parcourir mon image ligne par ligne
    		{
    		// Le morceau de code ci-dessus.
    		}
    	}

    Donc tout est identifiable avant l'appel de la méthode "process". La seule chose, c'est que les paramètres changent en fonction de l'image à traiter, à commencer par les dimensions.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  20. #20
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par ToTo13 Voir le message

    Donc tout est identifiable avant l'appel de la méthode "process". La seule chose, c'est que les paramètres changent en fonction de l'image à traiter, à commencer par les dimensions.
    C'est ce que tu dis, mais le code ne le prouve pas. Tout ce qui n'est pas local à la méthode (les champs), la jvm doit supposer que ça a pu être modifié de l'extérieur de la méthode. Que ce soit par l'appel à System.arraycopy ou par l'appel à ArrayOperations.Maximum
    Donc pour reprendre ton bout de code et ta question de comment aider la JVM à comprendre, je pense que ceci:
    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
     
    private int param1, param2, sewidth ;
    private int width, height ;
     
    public void process(BufferedImage image, BufferedImage result) // Traitements de mon image en fonction des paramètres récupérés.
    	{
    	int[] inbufferin = image.getDataBufferInt() ; // Version simplifiée...
    	int[] inbufferout = result.getDataBufferInt() ; // Version simplifiée...
     
    	int y, pos ;
    	for (y=pos=0 ; y < height ; y++, pos+=width) // Me permet de parcourir mon image ligne par ligne
    		{
    		System.arraycopy(intbufferin, pos, intbufferout, pos, width) ;
    		for (s=-1, p=pos-Param1 ; -sewidth <= s && 0 <= Param2+s ; s--, p-=Param1)
    			ArrayOperations.Maximum(intbufferin, p, intbufferout, pos, intbufferout, pos, width) ;
    		}
    	}
    pourrait déjà être amélioré comme ceci

    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
    private int param1, param2, sewidth ;
    private int width, height ;
     
    public void process(BufferedImage image, BufferedImage result) // Traitements de mon image en fonction des paramètres récupérés.
    	{
            int param1 = this.param1;
            int param2 = this.param2;
            int sewidth = this.sewidth;
            int width = this.width;
            int height = this.height ;
    	int[] inbufferin = image.getDataBufferInt() ; // Version simplifiée...
    	int[] inbufferout = result.getDataBufferInt() ; // Version simplifiée...
     
    	int y, pos ;
    	for (y=pos=0 ; y < height ; y++, pos+=width) // Me permet de parcourir mon image ligne par ligne
    		{
    		System.arraycopy(intbufferin, pos, intbufferout, pos, width) ;
                    int limit = sewidth < param2? -sewidth : -param2; // pas sur que ça aide, mais simplifions le test de boucle
    		for (s=-1, p=pos-param1 ; limit <= s ; s--, p-=param1)
    			ArrayOperations.Maximum(intbufferin, p, intbufferout, pos, intbufferout, pos, width) ;
    		}
    	}
    Ensuite, si la jvm n'inline pas d'elle même le contenu de ArrayOperations.Maximum, j'opterais pour copier son code dans la boucle. C'est moche, mais du point de vue de ArrayOperations.Maximum, rien ne garantie que les opérations se font dans les limites du tableau => impossible de faire sauter le boundary check.

Discussions similaires

  1. Réponses: 1
    Dernier message: 29/06/2010, 15h50
  2. Connaître les requêtes reçues par Oracle XE
    Par benben02 dans le forum Administration
    Réponses: 1
    Dernier message: 08/12/2008, 08h44
  3. Comment connaître les fichiers visibles par le serveur
    Par Najdar dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 10/04/2008, 13h41
  4. Réponses: 1
    Dernier message: 11/12/2007, 17h34
  5. [Tableaux] Suivre les modifications faits par chaque utilisateur
    Par dessinateurttuyen dans le forum Langage
    Réponses: 7
    Dernier message: 19/07/2006, 10h05

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