Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Autres questions


Index du Forum » Autres questions » Optimisation possible ?
Ninestars Hors ligne Membre Points: 2451 Défis: 24 Message

Optimisation possible ?

Posté le 14/07/2015 01:10

Bonjour,
voici un problème que je viens de rencontrer, il s'agit d'optimiser plusieurs calculs en utilisant une variable supplémentaire, ce qui évite de calculer plusieurs fois la même chose :
float var = focal / z_delta;
int x_screen = x_delta * var;
int y_screen = y_delta * var
int radius_screen = radius * var;
Ce qui est embetant, ou du moins pas très logique, c'est que j'ai exactement les mêmes performances qu'en supprimant var et en recalculant focal / z_delta 3 fois...
Alors je me dis que c'est surement une mauvaise gestion du processeur, il doit aller chercher var à chaque fois, donc perd du temps, ou un truc du genre. Est-ce la raison, et est-il possible d'optimiser cette partie ?
Merci bien


Dark storm Hors ligne Labélisateur Points: 11571 Défis: 176 Message

Citer : Posté le 14/07/2015 08:48 | #


T'as essayé de compliler ça avec GCC ? Après, si c'est toujours pas optimisé, y'a qu'une seulle solution, l'ASM
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir En ligne Administrateur Points: 22772 Défis: 149 Message

Citer : Posté le 14/07/2015 09:07 | #


À mon avis il est possible que ton compilateur optimise en utilisant la variable intermédiaire tout seul.

Après, à une fin de complétude, j'ajouterai que le code n'est pas strictement le même, parce que comme on évite membre * var, on diminue le risque d'overflow, mais comme on calcule tout de suite focal / z_delta, on a un risque de perte de précision.

Si tu es sur le SDK, tu peux trouver l'adresse de ta fonction dans le fichier FXAddinROR.map (à la casse près, je ne sais plus trop) et voir ce que le code fait vraiment.

Après au niveau purement assembleur, pour aller chercher une variable ça va se passer à peu près comme ça, en mettant quelques constantes :
mov.l @(3, r15), r2

C'est-à-dire lire 4 octets sur la pile, alors que pour le calcul des de la division ce sera plus proche de ça :
mov.l @(1, r15), r1
mov.l @(2, r15), r2
div   r1, r2

Rien de bien extraordinaire, tu me diras : trois instructions pour récupréer la valeur dans r2 au lieu d'une.

Sauf que la division elle ne se fait pas comme ça. Je ne sais pas si le compilateur interprète ta division comme une division flottante ou entière, mais le fait est que la division entière prend plus de 70 cycles sur SH3 (moins de 20 sur SH4 grâce au FPU). Quant à la division flottante, gcc utilise ses propres fonctions mais je pense qu'il y a de la division entière dedans aussi, donc c'est sans doute encoure pire.

Donc tu devrais avoir une différence très significative ici.
Ninestars Hors ligne Membre Points: 2451 Défis: 24 Message

Citer : Posté le 15/07/2015 17:28 | #


Merci, alors j'ai ça ;
Avec la variable
Cliquer pour enrouler
      Scene_Spac    70                float a = camera->focal / z_delta;
    00000212 5159                   MOV.L       @(36,R5),R1
    00000214 D323                   MOV.L       L307+34,R3 ; __divls
    00000216 430B                   JSR         @R3
    00000218 6063                   MOV         R6,R0
    0000021A D21D                   MOV.L       L307+14,R2 ; __itos
    0000021C 420B                   JSR         @R2
    0000021E 0009                   NOP
      Scene_Spac    71    
      Scene_Spac    72                int x_screen = x_delta * a;
    00000220 D31B                   MOV.L       L307+14,R3 ; __itos
    00000222 6503                   MOV         R0,R5
    00000224 430B                   JSR         @R3
    00000226 6073                   MOV         R7,R0
    00000228 D218                   MOV.L       L307+10,R2 ; __muls
    0000022A 420B                   JSR         @R2
    0000022C 6153                   MOV         R5,R1
    0000022E D31A                   MOV.L       L307+22,R3 ; __stoi
    00000230 430B                   JSR         @R3
    00000232 0009                   NOP
    00000234 1F01                   MOV.L       R0,@(4,R15)
      Scene_Spac    73                int y_screen = y_delta * a;
    00000236 D316                   MOV.L       L307+14,R3 ; __itos
    00000238 430B                   JSR         @R3
    0000023A 60F2                   MOV.L       @R15,R0
    0000023C D213                   MOV.L       L307+10,R2 ; __muls
    0000023E 420B                   JSR         @R2
    00000240 6153                   MOV         R5,R1
    00000242 D315                   MOV.L       L307+22,R3 ; __stoi
    00000244 430B                   JSR         @R3
    00000246 0009                   NOP
    00000248 2F02                   MOV.L       R0,@R15
      Scene_Spac    74                int radius_screen = star->radius * a;
    0000024A D311                   MOV.L       L307+14,R3 ; __itos
    0000024C 430B                   JSR         @R3
    0000024E 5043                   MOV.L       @(12,R4),R0
    00000250 D20E                   MOV.L       L307+10,R2 ; __muls
    00000252 420B                   JSR         @R2
    00000254 6153                   MOV         R5,R1
    00000256 D310                   MOV.L       L307+22,R3 ; __stoi
    00000258 430B                   JSR         @R3
    0000025A 0009                   NOP

Sans la variable
Cliquer pour enrouler
  Scene_Spac    70                int x_screen = x_delta * camera->focal / z_delta;
    00000214 5769                   MOV.L       @(36,R6),R7
    00000216 51F1                   MOV.L       @(4,R15),R1
    00000218 D321                   MOV.L       L306+34,R3 ; __divls
    0000021A 0177                   MUL.L       R7,R1
    0000021C 011A                   STS         MACL,R1
    0000021E 430B                   JSR         @R3
    00000220 6053                   MOV         R5,R0
    00000222 2F02                   MOV.L       R0,@R15
      Scene_Spac    71                int y_screen = y_delta * camera->focal / z_delta;
    00000224 51F3                   MOV.L       @(12,R15),R1
    00000226 0177                   MUL.L       R7,R1
    00000228 D31D                   MOV.L       L306+34,R3 ; __divls
    0000022A 011A                   STS         MACL,R1
    0000022C 430B                   JSR         @R3
    0000022E 6053                   MOV         R5,R0
    00000230 1F01                   MOV.L       R0,@(4,R15)
      Scene_Spac    72                int radius_screen = star->radius * camera->focal / z_delta;
    00000232 5143                   MOV.L       @(12,R4),R1
    00000234 D31A                   MOV.L       L306+34,R3 ; __divls
    00000236 0177                   MUL.L       R7,R1
    00000238 011A                   STS         MACL,R1
    0000023A 430B                   JSR         @R3
    0000023C 6053                   MOV         R5,R0
    0000023E 6603                   MOV         R0,R6

Alors je comprend vraiment pas ce que cela signifie, est-ce que tu pourais y jetter un oeil ? Merci

moins de 20 sur SH4 grâce au FPU
Le FPU améliore aussi les division entière ?

Ajouté le 15/07/2015 à 17:31 :
Et je compile avec le SDK
Lephenixnoir En ligne Administrateur Points: 22772 Défis: 149 Message

Citer : Posté le 15/07/2015 17:40 | #


Ninestars a écrit :
Alors je comprend vraiment pas ce que cela signifie, est-ce que tu pourais y jetter un oeil ? Merci

Alors, rapidement, il faut regarder les jsr (jump to subroutine) qui sont des appels de fonctions, et chercher quel est le symbole utilisé, ici celui qui est chargé dans le registre r3 :

[b]Avec la variable :[/b]
__divls
__itos * 4
__muls * 3
__stoi * 3

[b]Sans la variable :[/b]
__divls * 3

À l'évidence, __divls fait une division (facile de savoir laquelle ), et __itos et __stoi sont des fonctions de conversion (i to s, donc integer to... single ou simple je suppose, pour signifier simple précision par opposition à la double précision, et single/simple to integer). __muls, c'est évidemment une multiplication.

On peut constater qu'avec la variable on ne fait qu'une division mais on se tape des conversions ! Ce qui explique que ton code ne soit pas plus rapide finalement.

Il faut que tu gères mieux les types, éventuellement, si tu veux essayer de faire comprendre au compilateur qu'il faut tout faire un flottant et éviter les conversions en entiers !

Ninestars a écrit :
Le FPU améliore aussi les division entière ?

Non, mais vu que la division entière prend toujours 70 cycles alors que la double conversion et division flottante prend moins de 20 cycles, tu penses qu'on va se gêner ?

Ninestars a écrit :
Et je compile avec le SDK

Je m'en suis douté en voyant l'assembleur...
Dark storm Hors ligne Labélisateur Points: 11571 Défis: 176 Message

Citer : Posté le 15/07/2015 17:42 | #


Enfin, le FPU de la SH4, il est pratique sur la SH4, qui elle à la base n'a pas tellement de problèmes de vitesse
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir En ligne Administrateur Points: 22772 Défis: 149 Message

Citer : Posté le 15/07/2015 17:43 | #


Dark storm a écrit :
Enfin, le FPU de la SH4, il est pratique sur la SH4, qui elle à la base n'a pas tellement de problèmes de vitesse

T'as pas fait de calculs de prévision pour de la 3D toi...
Dark storm Hors ligne Labélisateur Points: 11571 Défis: 176 Message

Citer : Posté le 15/07/2015 17:46 | #


Si, mais entre une SH3 et une SH4, la SH4 est un peu plus rapide, donc au final c'est plus la SH3 qui a besoin du FPU
Après, en absolu, les deux ont besoin de plus qu'un FPU pour la 3D
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir En ligne Administrateur Points: 22772 Défis: 149 Message

Citer : Posté le 15/07/2015 18:01 | #


Dark storm a écrit :
Après, en absolu, les deux ont besoin de plus qu'un FPU pour la 3D

Oui, ben il va déjà falloir faire sans pour la SH3... x)

Si j'arrive à faire des tests pendant les vacances, j'essaierai d'avoir quelque chose d'assez optimisé pour éviter d'avoir à overclocker la machine. Bon, au pire, c'est pas hyper coûteux si c'est pas trop puissant, mais par principe quoi.

</hs>
Ninestars Hors ligne Membre Points: 2451 Défis: 24 Message

Citer : Posté le 15/07/2015 18:29 | #


J'aime bien avec toi, les reponses sont toujours pro
D'accord donc je compense les gains par les conversions... Donc faire du tout flottant pourrait être plus rapide, enfin juste pour ces 3 calculs, parce que j'ai changé à d'autres endroits des float en int et le gain est important

d'accord, en effet c'est plus atucieux de faire comme ça
Lephenixnoir En ligne Administrateur Points: 22772 Défis: 149 Message

Citer : Posté le 15/07/2015 18:35 | #


Ninestars a écrit :
Donc faire du tout flottant pourrait être plus rapide, enfin juste pour ces 3 calculs, parce que j'ai changé à d'autres endroits des float en int et le gain est important

Ben, de toute façon, tous les calculs doivent être fait en flottant, alors peut-être qu'en n'utilisant que des variables et opérations flottantes le compilateur évitera les conversions en int.

Ninestarts a écrit :
d'accord, en effet c'est plus atucieux de faire comme ça

L'optimisation est presque une science...

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2022 | Il y a 100 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd