Derniers sujets
» Tyrann I
Hier à 23:18 par drpsy

» Route en effet 3d
Hier à 19:24 par Dbug

» Grand concours de programmation
Lun 17 Déc 2018 - 11:01 par drpsy

» Fonctionnement des graphismes « old school »
Dim 16 Déc 2018 - 9:58 par Dbug

» Adventureland
Jeu 13 Déc 2018 - 21:32 par Symoon

» Rodmän "SPECIAL MULTI FORMAT TRIPLE CASSETTE"
Jeu 13 Déc 2018 - 21:30 par Symoon

» Podcast ORIC en préparation !
Mer 12 Déc 2018 - 19:09 par Dbug

» Oric Kong en C version finale
Lun 10 Déc 2018 - 22:58 par Ladywasky

» besoin d'un affichage printf plus rapide
Dim 9 Déc 2018 - 22:06 par drpsy

» Oric spleen...spline?
Sam 8 Déc 2018 - 23:19 par kenneth

» Oric Explorer v2.0.... Bonne et mauvaise nouvelles
Mar 4 Déc 2018 - 15:04 par laurentd75

» Psycho III
Sam 1 Déc 2018 - 14:33 par Symoon

» rêve de jeu ...
Mer 28 Nov 2018 - 17:34 par Dbug

» Telestrat sur Ebay
Dim 25 Nov 2018 - 17:58 par Jede

» Editeur assembleur Micrologic
Dim 25 Nov 2018 - 15:25 par Symoon

Qui est en ligne ?
Il y a en tout 1 utilisateur en ligne :: 0 Enregistré, 0 Invisible et 1 Invité :: 1 Moteur de recherche

Aucun

Le record du nombre d'utilisateurs en ligne est de 29 le Mer 25 Fév 2015 - 14:01
Connexion

Récupérer mon mot de passe

Statistiques
Nous avons 163 membres enregistrés
L'utilisateur enregistré le plus récent est Camille2005

Nos membres ont posté un total de 7590 messages dans 574 sujets
Portail ORIC




besoin d'un affichage printf plus rapide

Poster un nouveau sujet   Répondre au sujet

Aller en bas

besoin d'un affichage printf plus rapide

Message par goyo le Mer 28 Nov 2018 - 18:26

Hello,
j'ai vite codé un mini visualiseur de mémoire mais l'affichage avec printf est lent pour visualiser les valeurs Int et Char (adresse mémoire et sa valeur). Y aurait il en C un moyen d'optimiser la chose .. ?
Code:

#include <lib.h>

void MemoryDisplay(unsigned int currentAddr,char mode)
{
 int x;
 int y;
  
 int rowCount=24;
 int colCount=40;
 unsigned char byte;
 unsigned int addrIndex=currentAddr;
 x=2;
 while(x<colCount)
    {        
    y=4;
            while(y<rowCount)
            {
                byte=peek(addrIndex);      
  
 if (byte<30||byte>126)
 byte='.';
 
 if (mode==0)
                {
    gotoxy(x,y);
 printf("%x=",addrIndex);
        }
                gotoxy(x+6,y);printf("%d  ",byte);
 gotoxy(x+10,y);putchar(byte);

 addrIndex++;
 y++;
    }
 x+=13;
    }  
}
void main()
{    
    unsigned int currentAddr=0x1c0;
 unsigned int pokeAddr;
 unsigned int currentAddrSave;
 char mode;
 int i=0;
 unsigned char flagFin;
 char a;
 unsigned char  byte;
 
 poke(0x26A,10);
 poke(0x24E,8);
 poke(0x24F,6);
 
 flagFin=1;
 mode=1;
 cls();
 MemoryDisplay(currentAddr,0);

 gotoxy(0,0);printf("'O'-60 'P'+60 'G'Goto 'C'POKE (Q)uit");
 do{
 
 currentAddrSave=currentAddr;
 a=key();
 
 if( a != 0 )
 {
    if(a==  'Q' || a=='A')
    {
     flagFin=0;
        }
 if(a==11)
 {
 if (currentAddr>0)
 {
 currentAddr--;
 }
 }
 if(a==10)
 {
 if (currentAddr<65535)
 {
 currentAddr++;
 }
 }
 
 if(a==  'O'|| a==8)
 {
 if (currentAddr>0)
 {
 currentAddr-=60;
 }
 }
 if(a==  'P'|| a==9)
 {
 if (currentAddr<65535)
 {
 currentAddr+=60;
 }
 }
 if(a==  'G')
 {
    
 gotoxy(2,26);printf("GOTO ADDR(hex):");
 scanf("%x", ¤tAddr);
 cls();
 MemoryDisplay(currentAddr,0);
 
 }
 if (a=='C'|| a=='K')
 {
    
     gotoxy(2,24);printf("POKE ADDR(hex):");
 scanf("%x", &pokeAddr);
                    
        gotoxy(2,25);printf("VALUE (dec):");
 scanf("%d", &byte);    
 poke(pokeAddr,byte);
 gotoxy(2,24);printf("                                      ");          
 gotoxy(2,25);printf("                                      ");          
 gotoxy(2,26);printf("POKE ADDR : %x  = %d ",pokeAddr,byte);
 
 MemoryDisplay(currentAddr,0);
 }
 }
 if (currentAddrSave==currentAddr)
     mode=1;
 else
     mode=0;

 //gotoxy(2,25);printf("key=%d  ",a);
 MemoryDisplay(currentAddr,mode);
 
 } while(flagFin);
}

Fichiers joints
livemem.zip (3 Ko) Téléchargé 7 fois
avatar
goyo

Messages : 96
Date d'inscription : 02/05/2014
Age : 47
Localisation : Massy

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Ladywasky le Jeu 29 Nov 2018 - 14:49

On peut trouver ça dans l'OSDK.
Mais je ne pense pas que dans ce cas ce soit l'affichage le plus lent mais la conversion du printf des adresses (qui sont des entiers) en chaînes de caractères affichable.
avatar
Ladywasky

Messages : 100
Date d'inscription : 25/08/2018

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Jeu 29 Nov 2018 - 15:27

Salut Gweg / Goyo,

Je vois qu'il y a beaucoup (trop ?) d'appels à gotoxy() dans ton code et que tu pourrais sans doute en éviter certains.
Et que tu fais également des appels à printf() ET à putchar(), que tu pourrais sans doute rassembler dans un seul printf()

Exemple:

Code:

gotoxy(x+6,y);printf("%d  ",byte);
 gotoxy(x+10,y);putchar(byte);

gagnerait sans doute (à voir... et sous réserve que printf() dans l'OSDK accepte l'argument numérique pour les spécificateurs de type) à être transformé en:
Code:

gotoxy(x+6,y);printf("%3d  %c", byte, byte); // affichage de la 1ere valeur avec padding sur 3 caractères

Par ailleurs, je ne sais pas comment est défini peek (si c'est un #define ou une fonction), mais si c'est une fonction, l'overhead est énorme et il vaut mieux utiliser le #define suivant :
Code:

#define peek(x) (*x)

Après, printf() est évidemment très lent vu qu'il doit interpréter de façon complexe une chaîne de caractères  avec une multitude d'arguments possibles, donc tu ferais sans doute mieux de te définir un équivalent de la fonction putchar() pour afficher un nombre décimal...

Exemple naïf en C pour afficher un nombre positif entre 0 et 255 (qui d'après ce que j'ai compris est ton besoin):
Code:

/* Affichage d'un entier entre 0 et 255 */
void putdec(unsigned char n) {
  if (n > 99) { // affichage chiffre  des centaines
    putchar('0' + n / 100);
  }
  if (n > 9) { // affichage chiffre des dizaines
    putchar('0' + (n % 100) / 10);
  }
  putchar('0' + n % 10); // affichage du chiffre des unités
}

Je suis pas sûr que ce soit hyper performant en C, mais c'est peut-être déjà plus performant que printf(), et sinon ça peut se recoder en asm 6502 assez facilement (sauf pour les divisions  Smile )...

Voilà, ce n'est sans doute pas la réponse avec la solution miracle que tu attendais, mais j'espère quand même t'avoir un peu aidé  Wink

A+
Laurent


Dernière édition par laurentd75 le Jeu 29 Nov 2018 - 15:37, édité 1 fois
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Jeu 29 Nov 2018 - 15:32

Après réflexion, petit "refactoring" de la fonction d'affichage d'un entier pour éviter les divisions:

Code:

/* Affichage d'un entier entre 0 et 255 */
void putdec(unsigned char n) {
  // affichage chiffre  des centaines
  if(n > 199) {
    putchar('2');
    n -= 200;
  }
  else if (n > 99) {
    putchar('1');
    n -= 100;
  }
  // affichage des dizaines
  if (n > 89) putchar('9');
  else  if (n > 79) putchar('8');
  else  if (n > 69) putchar('7');
  else  if (n > 59) putchar('6');
  else  if (n > 49) putchar('5');
  else  if (n > 39) putchar('4');
  else  if (n > 29) putchar('3');
  else  if (n > 19) putchar('2');
  else  if (n > 9) putchar('1');

  // affichage du chiffre des unités
  putchar('0' + n % 10);
}
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par goyo le Lun 3 Déc 2018 - 17:49

laurentd75 a écrit:Après réflexion, petit "refactoring" de la fonction d'affichage d'un entier pour éviter les divisions:

Code:

/* Affichage d'un entier entre 0 et 255 */
void putdec(unsigned char n) {
  // affichage chiffre  des centaines
  if(n > 199) {
    putchar('2');
    n -= 200;
  }
  else if (n > 99) {
    putchar('1');
    n -= 100;
  }
  // affichage des dizaines
  if (n > 89) putchar('9');
  else  if (n > 79) putchar('8');
  else  if (n > 69) putchar('7');
  else  if (n > 59) putchar('6');
  else  if (n > 49) putchar('5');
  else  if (n > 39) putchar('4');
  else  if (n > 29) putchar('3');
  else  if (n > 19) putchar('2');
  else  if (n > 9) putchar('1');

  // affichage du chiffre des unités
  putchar('0' + n % 10);
}
Merci Laurent pour ces infos.
j'ai essayé la méthode putdec() mais elle s'avère plus lente que le printf("%d",byte);

je pense qu'il faudrait la faire en assembleur c'est la seule solution que je vois.
avatar
goyo

Messages : 96
Date d'inscription : 02/05/2014
Age : 47
Localisation : Massy

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Lun 3 Déc 2018 - 18:30

Bizarre, je pensais pourtant que ce serait plus  performant, même avec plusieurs tests et appels à putchar() !! Shocked
==> j'ai qd même l'impression que ce compilo est vraiment naze, car je vois pas comment des appels à des fonctions peuvent être plus lents qu'une division en 6502 ??!! (car je suppose que printf "%d" réalise des divisions...)

Autre piste avant de se lancer dans l'ASM:

Utiliser puts() et itoa() au lieu de printf() , normalement ça fait au moins gagner le temps de l'analyse syntaxique du printf()...:

==> Au lieu de
Code:
printf("%d",byte);

Essaie ça pour voir:
Code:

puts(itoa(byte));

NB: tu dois ajouter l'include suivant pour itoa() :
Code:

#include <stdlib.h>
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Lun 3 Déc 2018 - 18:39

ps - je me rappelle plus si c'est cc65 dans l'OSDK, mais is c'est le cas, le source de printf() est en ASM, pas en C, ceci explique sans doute que le printf() était + performant que mon "optimisation"...:
cf. https://github.com/cc65/cc65/blob/master/libsrc/common/_printf.s
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Dbug le Lun 3 Déc 2018 - 20:50

Vous pouvez aussi utiliser sprintf, en mettant en addresse de destination la position écran voulue:
sprint((char*)0xbb80+x+(y*40),"%d",valeur)
ca a le mérite de ne pas utiliser la fonction d'affichage du BASIC, ca tappe directement en mémoire.

Après si le but c'est juste de débogger, le plus rapide c'est d'afficher en hexadécimal, ca aussi le mérite de faire en sorte de pouvoir tout aligner a l'écran sans problème.

_________________

avatar
Dbug

Messages : 108
Date d'inscription : 06/01/2013

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par goyo le Mar 4 Déc 2018 - 13:41

laurentd75 a écrit:Après réflexion, petit "refactoring" de la fonction d'affichage d'un entier pour éviter les divisions:

Code:

/* Affichage d'un entier entre 0 et 255 */
void putdec(unsigned char n) {
  // affichage chiffre  des centaines
  if(n > 199) {
    putchar('2');
    n -= 200;
  }
  else if (n > 99) {
    putchar('1');
    n -= 100;
  }
  // affichage des dizaines
  if (n > 89) putchar('9');
  else  if (n > 79) putchar('8');
  else  if (n > 69) putchar('7');
  else  if (n > 59) putchar('6');
  else  if (n > 49) putchar('5');
  else  if (n > 39) putchar('4');
  else  if (n > 29) putchar('3');
  else  if (n > 19) putchar('2');
  else  if (n > 9) putchar('1');

  // affichage du chiffre des unités
  putchar('0' + n % 10);
}

j'ai fait quelques tests à l'aide de la fonction clock();

voici les valeur de temps écoulé:

avec "for()"
gotoxy(x,y); puts(itoa(byte));   =    527

gotoxy(x,y);printf("%d",byte);  =    431

gotoxy(x,y); putdec(byte);       =    513


avec "do while()"

gotoxy(x,y);printf("%x",byte); = 412

gotoxy(x,y);putdec(byte); = 490


donc "do while()" + "printf("%d",valeur) semble le plus rapide

code utilisé:

for(j=0;j<16;j++)
{
   for(y=1;y<25;y++)
   {
       for(x=2;x<39;x+=12)
       {
           gotoxy(x,y);printf("%d",byte);
       }
   }
}
avatar
goyo

Messages : 96
Date d'inscription : 02/05/2014
Age : 47
Localisation : Massy

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Mar 4 Déc 2018 - 14:50

Incroyable... Comme quoi, l'optimisation, c'est pas juste théorique, faut toujours valider par la pratique !!! :-)

Honnêtement, j'en reviens pas que puts(itoa(byte)) soit plus lent que printf(), c'est juste dingue, ça veut dire en gros que l'overhead de l'appel de fonction à  itoa() est plus important que le temps d'analyse syntaxique de la chaîne de format passée à printf() !! Et du coup je trouve aussi bizarre que ma fonction putdec(byte) soit plus rapide que puts(itoa(byte)), alors que ma fonction réalise de 1 à 3 appels à putchar()  !?

En tous cas, je vais me replonger dans les articles du CEO Mag sur les différents compilateurs (cc65, lcc) , et je ferai un peu de "métrologie" de mon côté également pour comparer le comportement et les perfs de chaque compilo...
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Mar 4 Déc 2018 - 15:00

PS - quoi qu'il en soit, je rejoins DBug sur le fait que si ton programme est destiné à être un outil de dev, il est sans doute préférable d'afficher les valeurs en hexa plutôt qu'en décimal, ça ira plus vite (un chiffre de moins à afficher en général), ce sera aligné, et généralement c'est plus intéressant d'avoir la valeur en hexa qu'en décimal...

En revanche, à part économiser un appel de fonction et l'overhead associé, je ne vois pas trop le gain d'utiliser sprintf() par rapport à printf()... Je pense (j'espère même)  que gotoxy() est optimisée et ne fait pas appel à une routine lente de la ROM... Et je ne suis pas persuacdé que le compilo C optimise  la multiplication par 40...  Very Happy
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Jede le Mar 4 Déc 2018 - 16:50

laurentd75 a écrit:Incroyable... Comme quoi, l'optimisation, c'est pas juste théorique, faut toujours valider par la pratique !!! :-)

Honnêtement, j'en reviens pas que puts(itoa(byte)) soit plus lent que printf(), c'est juste dingue, ça veut dire en gros que l'overhead de l'appel de fonction à  itoa() est plus important que le temps d'analyse syntaxique de la chaîne de format passée à printf() !! Et du coup je trouve aussi bizarre que ma fonction putdec(byte) soit plus rapide que puts(itoa(byte)), alors que ma fonction réalise de 1 à 3 appels à putchar()  !?

En tous cas, je vais me replonger dans les articles du CEO Mag sur les différents compilateurs (cc65, lcc) , et je ferai un peu de "métrologie" de mon côté également pour comparer le comportement et les perfs de chaque compilo...

Cela dépend comment c'est codé puts. Dans cc65, c'est du C qui appelle _write. Dans certaines libs, (conio) dans cc65, cela appelle cputc (affiche un caractère) quand on appelle cputs. Donc, les comportements sont différents en fonction des libs et des compilateurs.
avatar
Jede

Messages : 217
Date d'inscription : 20/04/2016
Localisation : Var

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par assinie le Mer 5 Déc 2018 - 17:06

Il y a des options de compilation qui permettent d'optimiser un peu le code généré: -Or, -Oi, -Os par exmple pour cc65.

Il y a aussi d'autres optimisations simples qui sont possibles avant de s'attaquer aux librairies du compilateur ou de passer à l'assembleur.

Par exemple utiliser des variables de type unsigned char à la place de variables de type int quand c'est possible, ce qui est le cas ici pour x et y.
Ou encore remplacer:
Code:

int rowCount = 24;
int colCount = 40;
par
Code:

#define rowCount 24
#define colCount 40
c'est possible ici puisque ces variables sont utlisées comme des constantes et le compilateur ne s'en aperçois pas, même en utilisant des options  de compilation.

En cumulant uniquement ces 2 modifications, les affectations et les tests sont simplifiés et il y a moins d'appels à des sous routines, et comme ces opérations sont faites à chaque itération de boucle, la boucle devrait tourner plus rapidement.

Par exemple, l'instruction y++ donne successivement:

Aucune modification:
Code:

;
; y++;
;
L000C:  ldy     #$05
        jsr     ldaxysp
        sta     regsave
        stx     regsave+1
        jsr     incax1
        ldy     #$04
        jsr     staxysp
        lda     regsave
        ldx     regsave+1

Utilisation de -Or:
Code:

;
; y++;
;
L000C:  ldy     #$05
        jsr     ldaxysp
        jsr     incax1
L0017:  ldy     #$04
        jsr     staxysp

Utilisation de unsigned char y (plus d'instructions mais aucun appel de routines)
Code:

;
; y++;
;
L000A:  ldy     #$00
        ldx     #$00
        lda     (sp),y
        pha
        clc
        adc     #$01
        ldy     #$00
        sta     (sp),y
        pla

Le même avec l'option -Or:
Code:

;
; y++;
;
L0014:  lda     (sp),y
        clc
        adc     #$01
L0017:  sta     (sp),y


On arrive à des optimisations similaires pour les tests des boucles while
Par exemple, on passe de
Code:

;
; while(y<rowCount)
;
L000E:  ldy     #$05
        jsr     ldaxysp
        jsr     pushax
        ldy     #$05
        jsr     ldaxysp
        jsr     tosltax
        jne     L000C

à
Code:

;
; while(y<rowCount)
;
        cmp     #$18
        bcc     L0014

en cumulant l'utilisation de #define et de unsigned char et des options de compilation.

Après, il reste aussi les routines des libraries qui ne sont pas toujours optimisées pour la vitesse d'exécution ou la taille du code généré, mais en faisant ces quelques modification, les boucles devraient gagner un peu en rapidité.

Il est toujours intéressant devoir le code produit par le compilateur dans plusieurs cas de figures, ça permet de voir quelles corrections apporter pour améliorer son programme.
Il y a aussi quelques trucs marrants dans le code généré suivant les options utilisées, il reste parfois des instructions inutiles et qui penvent donc être supprimées... à la main...

Et une fois que toutes les optimisations en C auront été faites, l'étape suivante sera de passer à l'assembleur avec aussi son lot de trucs et astuces divers et variés, et la traque de la moindre micro seconde perdue Smile
avatar
assinie

Messages : 226
Date d'inscription : 09/02/2014

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Dbug le Mer 5 Déc 2018 - 21:41

Apparemment mon message a été incompris...

laurentd75 a écrit:PS - quoi qu'il en soit, je rejoins DBug sur le fait que si ton programme est destiné à être un outil de dev, il est sans doute préférable d'afficher les valeurs en hexa plutôt qu'en décimal, ça ira plus vite (un chiffre de moins à afficher en général), ce sera aligné, et généralement c'est plus intéressant d'avoir la valeur en hexa qu'en décimal...
Le but de l'hexa vis a vis du decimal c'est la performance, et pas seulement "un chiffre de moins a afficher". C'est aux moins 10 fois plus rapide.
Afficher du decimal ca demande de faire des division et modulos par dix, alors que l'hexa c'est juste masquer 4 bit et utiliser une table d'affichage 0123456789ABCDEF pour afficher directos le nibble.

laurentd75 a écrit:En revanche, à part économiser un appel de fonction et l'overhead associé, je ne vois pas trop le gain d'utiliser sprintf() par rapport à printf()... Je pense (j'espère même)  que gotoxy() est optimisée et ne fait pas appel à une routine lente de la ROM...

sprintf n'affiche rien: Ca écrit dans un buffer, donc ca n'appelle pas la ROM pour faire quoi que ce soit.
Après, si au lieu de mettre un buffer on met une adresse écran, ca afficher sur l'écran, sans passer par la ROM.

Concernant Gotoxy, je vous invite a regarder le code plutôt qu'imaginer ce que le code fait: Tout le code source est dans OSDK/Lib:
Code:
; Do not print on the first screen columns. Screen attributes will be destroyed

_gotoxy
        ldy #$0         ; Grab first 8-bit parameter
        lda (sp),y
        sta tmp         ; Store column number (0-based)
        iny
        iny
        lda (sp),y      ; Grab second 8-bit parameter
        sta tmp+1       ; Move it to the X register
        lda $026a       ; Disable the cursor
        pha
        and #$fe        
        sta $026a      
        lda #$00
        jsr $f801
        lda tmp         ; Reload column number
        sta $0269       ; Store it where the OS can find it
        lda tmp+1       ; Now play with the row number
        sta $0268       ; Store it for the OS's sake
        jsr $da0c       ; Calculate screen row address
        lda $1f         ; Update pointers
        ldy $20
        sta $12
        sty $13
        pla             ; Restore state of cursor
        sta $026a
        lda #$01
        jmp $f801

laurentd75 a écrit:Et je ne suis pas persuacdé que le compilo C optimise  la multiplication par 40...  Very Happy
Le but est évidement pas de faire la multiplication, c'est un example: Si tu initializes ton pointeur a BB80 au début de ton écran, il te suffit de faire +=40 pour passer a la ligne suivante, ou de rajouter juste l'offset horizontal pour écrire plus loin sur la même ligne. Et quand tu fais ton sprintf y'a plus rien a calculer, tu passes juste ton pointeur comme étant l'adresse d'affichage.

_________________

avatar
Dbug

Messages : 108
Date d'inscription : 06/01/2013

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Ven 7 Déc 2018 - 19:33

Salut,

Pour l'hexa tu as raison DBug bien sûr, je n'avais même pas réfléchi au fait que c'était + performant car aucun besoin de division ou de modulo pour afficher les valeurs, du coup c'est clair que "le chiffre en moins à afficher" devient anecdotique :-) !

A propos de modulo, je n'avais pas réfléchi non plus pour ma routine d'affichage que le modulo est une opération aussi complexe que la division pour un 6502, donc si on veut vraiment afficher du décimal 0..255 il faudrait reprendre ma routine et modifier les tests pour les dizaines pour retrancher systématiquement la valeur des dizaines, de façon à pouvoir juste afficher ensuite les unités qui restent plutôt que d'avoir à faire un modulo.
(ex: if(n > 89} { cputchar('9'); n -= 90; })

Pour gotoxy(), ne pouvant pas vérifier moi-même au moment de ma réponse comment était codée cette routine j'ai voulu précisément suggérer de regarder comment c'était codé pour vérifier si c'était efficace ou pas. Et je voulais donc dire que si gotoxy() était efficace, du coup le sprintf() n'avait pas d'intérêt par rapport au printf(), puisque printf() écrit lui directement dans la mémoire de l'écran, tout comme sprintf() si on lui donne en argument une adresse mémoire écran plutôt que l'adresse d'une chaîne...

Par ailleurs... Merci beaucoup assinie pour toutes ces infos sur les optimisations, c'est vraiment très intéressant et instructif (ça pourrait même faire un très bon article pour le Mag je trouve...  Very Happy) . En tous cas ça me sera très utile je pense, et je creuserai le sujet car j'avoue ne m'être jamais intéressé encore aux options du compilateur...
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par drpsy le Ven 7 Déc 2018 - 20:56

dans l'OSDK, il y a un exemple "Advanced Print" qui permet d'afficher une chaîne à une position X,Y. Cette fonction s'appuie sur un tableau de pointeurs de lignes. Ce qui évite toute multiplication. Ca occupe quelques octets pour le tableau.
Mais sinon, une multiplication par 40, ça ne me parait pas sorcier :
X * 40 = X * 8 * (2 + 2 + 1)
R0 = X*8 : 3 décalages à gauche
R1 = R0*2
Puis additionner : R0+R1+R1.
L'opération ne prend que quelques octets en assembleur et aucun appel de routine.
Mais c'est plus long que le tableau de pointeurs.

_________________
>++++++++++[<++++++++>-]<.>++++++[<++++>-]<+.----.+++++++++++++..-------------.[-]
avatar
drpsy

Messages : 125
Date d'inscription : 20/07/2014
Age : 47
Localisation : Lagny sur Marne

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Sam 8 Déc 2018 - 0:13

Oui, DrPsy, effectivement, le mieux est de passer par un tableau avec les adresses de début de chaque ligne...

Sinon, la multiplication par 40, oui ça peut se faire par décalages et additions, mais seulement pour X <= 6, sinon après ça se complique un peu Very Happy


Dernière édition par laurentd75 le Sam 8 Déc 2018 - 13:04, édité 1 fois
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par drpsy le Sam 8 Déc 2018 - 9:56

Ma multiplication par 40 sur 2 octets avec la transformation de x,y en adresse écran. Ca ne doit pas être optimal encore... Le résultat est dans la variable tmp0. Et bon, ce serait plutôt à mettre dans le forum ASSEMBLEUR !

Code:

  clc
  lda #0
  sta tmp1+1
  lda _y          ;;; la position y
  sta tmp1      ;;; *8
  asl tmp1
  rol tmp1+1
  asl tmp1
  rol tmp1+1
  asl tmp1
  rol tmp1+1
  lda tmp1 ;;; sauve
  sta tmp3
  lda tmp1+1
  sta tmp3+1
  asl tmp1 ;;; *4
  rol tmp1+1
  asl tmp1
  rol tmp1+1
  lda tmp1            ;;; addition de (8*x) et de 4*(8*x)
  clc
  adc tmp3
  sta tmp3
  lda tmp1+1
  adc tmp3+1
  sta tmp3+1
                          ;;; fin de la multiplication par 40

  clc                    ;;; +x
  lda _x                 ;;;
  adc tmp3
  sta tmp0
  lda tmp3+1
  adc #0
  sta tmp0+1
  clc                      ;;; +addr debut ecran hires A000
  lda #0                      ;;; octet de poids faible. #$80 pour texte
   adc tmp0
   sta tmp0
   lda #$A0                   ;;; octet de poids fort. #$BB pour texte
  adc tmp0+1
  sta tmp0+1

_________________
>++++++++++[<++++++++>-]<.>++++++[<++++>-]<+.----.+++++++++++++..-------------.[-]
avatar
drpsy

Messages : 125
Date d'inscription : 20/07/2014
Age : 47
Localisation : Lagny sur Marne

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par drpsy le Sam 8 Déc 2018 - 10:07

J'ai fait une fonction en assembleur appelable en C (OSDK) pour afficher un caractère en Hires :
Code:

extern unsigned char PGS_putc(unsigned char x, unsigned char y, unsigned char c);
PGS_putc(  5 , 50 , 21 );

Ca m'a permis d'écrire du texte en hires avec un jeu de caractères spécial (d'où le 21...) sur 2 octets de large.



_________________
>++++++++++[<++++++++>-]<.>++++++[<++++>-]<+.----.+++++++++++++..-------------.[-]
avatar
drpsy

Messages : 125
Date d'inscription : 20/07/2014
Age : 47
Localisation : Lagny sur Marne

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par laurentd75 le Sam 8 Déc 2018 - 17:09

Merci DrPsy pour ta routine de multiplication en asm, c'est là qu'on voit que c'est quand même assez vite très fastidieux le 6502, et encore, là c'est un cas particulier et assez "simple"... J'avoue que quand je suis passé au 68000 sur Atari ST en sortant de l'Oric à l'époque, je n'ai pas trop regretté le 6502 !! Very Happy

A part ça, on dirait que tu es en train de nous préparer un jeu sympa dis-donc... Smile Smile Smile
avatar
laurentd75

Messages : 244
Date d'inscription : 09/08/2014
Age : 47
Localisation : Paris

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Dbug le Sam 8 Déc 2018 - 21:17

A noter que la routine qui fait la multiplication par 40 et ajoute l'adresse écran. occupe 76 octets, donc pour le mode TEXT, le gain de place est minimal et la performance dramatiquement pire.

En mode HIRES, ca se défend, mais uniquement si on est limite en mémoire Smile

Un avantage supplémentaire de la table, c'est la possibilité de gérer les dépassements de facon invisible en ayant de 200 a 255 les valeurs qui pointent vers un buffer "poubelle", ca simplifie le clipping Smile

_________________

avatar
Dbug

Messages : 108
Date d'inscription : 06/01/2013

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Jede le Dim 9 Déc 2018 - 10:52

laurentd75 a écrit:Salut,
Par ailleurs... Merci beaucoup assinie pour toutes ces infos sur les optimisations, c'est vraiment très intéressant et instructif  (ça pourrait même faire un très bon article pour le Mag je trouve...  Very Happy) . En tous cas ça me sera très utile je pense, et je creuserai le sujet car j'avoue ne m'être jamais intéressé encore aux options du compilateur...

Le plus simple au niveau des optims, c'est tout de même de passer les déclarations en unsigned char quand on sait qu'on ne dépassera pas 255.

Je pense qu'Assinie aime bien regarder le code source généré par cc65, donc, il est assez bien placé pour expliquer comment coder tel truc avec cc65. De mon coté, j'ai plutôt tendance à passer directement en asm certaines fonctions, quand je sais ou quand je vois que ça rame.

De mon coté, je connais plus (+) les libs cc65, donc je sais que les appels que je fais peuvent être plus ou moins long. C'est souvent le cas avec cc65 : les fonctions peuvent être assez lourdes car c'est un compilo générique qui cible toutes (bcp) les targets 6502. Par exemple, il n'y a pas de proto simple pour afficher une string, j'ai donc des extern de fonctions pour appeler directement des routines plus rapides à l'affichage.

Les libs conio et tgi de CC65 sont lentes car elles ne sont pas adaptées aux machines (on passe parfois par plusieurs variables avant d'appeler une routine), les proto ne sont pas adaptés. Mais comme évoqué plus haut, cela permet de prototyper rapidement des trucs avant de remplacer les appels par des trucs plus rapides.

Il serait possible de faire une lib "TGI" dédiée à l'atmos qui serait beaucoup plus rapide par exemple.
avatar
Jede

Messages : 217
Date d'inscription : 20/04/2016
Localisation : Var

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par drpsy le Dim 9 Déc 2018 - 22:06

@Laurent : l'idée d'un nouveau jeu vient de ma fille, elle a des talents indéniables de scénariste. Le dessin de la police est de mon fils. LOL.
@Dbug : oui ok. je préfère aussi la table. C'était juste pour l'exercice de style. Mais par rapport à la proc gotoxy, j'avoue que je n'aime pas trop les appels aux routines en ROM du BASIC.



_________________
>++++++++++[<++++++++>-]<.>++++++[<++++>-]<+.----.+++++++++++++..-------------.[-]
avatar
drpsy

Messages : 125
Date d'inscription : 20/07/2014
Age : 47
Localisation : Lagny sur Marne

Revenir en haut Aller en bas

Re: besoin d'un affichage printf plus rapide

Message par Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous pouvez répondre aux sujets dans ce forum