1

Salut

En GFA, y a-t-il un moyen plus rapide que BYTE / CARD / LONG pour lire une donnée en mémoire ?
J'ai une boucle WHILE...WEND pour faire une recherche avec BYTE{adresse%} mais je trouve pas ça super rapide.
Des indices ? smile
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

2

Me semble que ces instructions sont les plus rapides, et entre elles LONG{} > INT{} > BYTE{} (du point de vue rapidité lecture /taille données)
Du point de vue optimisation, il vaudrait mieux voir ce que tu mets dans ta boucle WHILE...WEND et adapter en conséquence : ne pas faire recalculer pour rien, utiliser les INC adresse% plutôt que adresse%=adresse%+1, etc.
Ou carrément changer de méthode de lecture de ta zone mémoire.
Tu peux nous faire lire ta boucle ?

3

Strider :
Salut

En GFA, y a-t-il un moyen plus rapide que BYTE / CARD / LONG pour lire une donnée en mémoire ?
J'ai une boucle WHILE...WEND pour faire une recherche avec BYTE{adresse%} mais je trouve pas ça super rapide.
Des indices ? smile


Comme l'a dit Rajah, on peut avoir un exemplaire de ta boucle ? Dans le pire des cas, une 'little routine asm' te règlera surement le probleme, car la lecture d'octet est un exercice de base pour l'assembleur.

GT Turbo octopus
avatar
Accrochez vous ca va être Cerebral !!

4

PEEK et POKE, avec SLPEEK et SLPOKE je crois, si mes souvenirs sont bons smile Enfin pas certains de la syntaxe...

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

5

Désolé, je vous ai embêté pour rien avec mes histoires... en fait c'est le nouvel interpréteur du GFA (GFA-Run) qui est très lent angry

Pour info, c'est une boucle toute bête de ce genre :

WHILE position% < maximum%
    IF BYTE{position%}=90 AND BYTE{ADD(position%,1)}=80
        ... etc ...
    END IF
    ADD position%,1
WEND


Et je voulais juste savoir si BYTE est plus rapide que PEEK. Apparemment oui.
Mais si Rajah dit juste (et je le crois car c'est un gourou du GFA smile ), je devrais de remplacer les 2 BYTE par 1 INT ?
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

6

@Strider : OUI !!!!!!!
surtout là, INT{position%}=truc&, avec le truc& à base de 90+80 (genre truc&=CVI(chr$(90)+chr$(80) ?) que tu auras défini EN DEHORS de ton WHILE-WEND.
Tu incrémentes de 2, et comme ça une seule lecture, sur une adresse paire (pas bien de lire sur les impaires, ça lui fait faire des manips qui consomme du temps, il me semble).

Et puis, un ADD position%,1 c'est inutile, il vaut mieux un "INC position%" si le décalage n'est que de 1.

7

Rajah Lone :
@Strider : OUI !!!!!!!
surtout là, INT{position%}=truc&, avec le truc& à base de 90+80 (genre truc&=CVI(chr$(90)+chr$(80) ?) que tu auras défini EN DEHORS de ton WHILE-WEND.
Tu incrémentes de 2, et comme ça une seule lecture, sur une adresse paire (pas bien de lire sur les impaires, ça lui fait faire des manips qui consomme du temps, il me semble).

Et puis, un ADD position%,1 c'est inutile, il vaut mieux un "INC position%" si le décalage n'est que de 1.


Yes, master ! grin

Je vais chronométrer tout ça et faire des tests pour en avoir le coeur net une bonne fois pour toutes smile
Et si ça intéresse quelqu'un je mettrai les résultats ici.

Tiens j'avais pas pensé à lecture sur les adresses impaires... avec un 68000 c'est mal smile
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

8

Oups, si tu veux lire un 'ZP' et que ton Z est à une adresse impaire, ça ne va pas marcher...
Donc ça dépend de ce que tu cherches. C'est dans un fichier spécial et formaté, ou du texte ?

Si c'est du texte :
WHILE position% < maximum% 
    IF BYTE{position%}=90
       IF BYTE{SUCC(position%)}=80 
        ... etc ... 
      END IF 
    END IF 
    INC position%
WEND 

Avec ça, tu réduis la lecture : pas besoin de faire un IF en trop s'il ne trouve pas de 'Z'.

Une autre chose, il ne faut pas que SUCC(positioncheeky dépasse maximum%, c'est plus prudent si ton maximum% se trouve dans une zone mémoire qui ne pourrait pas t'appartenir.

9

@Rajah: en fait je veux extraire des musiques SNDH depuis des exécutables, donc comme il s'agit d'exécutables ST je suppose que ce genre de données commence sur une adresse paire.
De plus je recherche une chaine de 4 caractères ("SNDH"), j'ai donc testé avec un LONG{recherche%} où recherche% vaut CVL("SNDH").

J'ai fait des tests et les résultats sont surprenants !!!

Voici les bouts de code que j'ai testés :

Code 1 :
WHILE position% < maximum%
    IF BYTE{position%}=90 AND BYTE{ADD(position%,1)}=80 AND BYTE{ADD(position%,2)}=70 AND BYTE{ADD(position%,3)}=60
        ' traitement
    END IF
    ADD position%,2
WEND


Code 2 :
WHILE position% < maximum%
    IF BYTE{position%}=90 AND BYTE{ADD(position%,1)}=80 AND BYTE{ADD(position%,2)}=70 AND BYTE{ADD(position%,3)}=60
        ' traitement
    END IF
    ADD position%,2
WEND


Code 3 :
WHILE position% < maximum%
    IF LONG{position%}=recherche%
        ' traitement
    END IF
    ADD position%,2
WEND


(la durée d'exécution est donnée en millisecondes grâce à l'instruction TIMER)

Les deux premiers codes donnent les MEMES résultats, contrairement à ce que Rajah et moi croyions smile
Le compilateur doit certainement optimiser ce genre de code (j'utilise la version 3.6TT).

Les tests ont porté sur la recherche de la chaine "SNDH" dans un fichier de 857 Ko.

Performance des deux premiers codes :

Steem 8 MHz : 24,675 s
Falcon030 16 couleurs : 6,62 s
FalconCT60, TTRam désactivée : 1,185 s
FalconCT60, TTRam activée : 0,36s

Soit une vitesse de traitement de :
Steem 8 MHz : 34,7 Ko/s
Falcon030 16 couleurs : 129 Ko/s
FalconCT60, TTRam désactivée : 723 Ko/s
FalconCT60, TTRam activée : 2 380 Ko/s

Performance du troisième code :

Steem 8 MHz : 10,58 s
Falcon030 16 couleurs : 2,735 s
FalconCT60, TTRam désactivée : 0,48 s
FalconCT60, TTRam activée : 0,195 s

Soit une vitesse de traitement de :
Steem 8 MHz : 81 Ko/s
Falcon030 16 couleurs : 313,34 Ko/s
FalconCT60, TTRam désactivée : 1785 Ko/s
FalconCT60, TTRam activée : 4394 Ko/s

D'après mes conclusions :
1/ la recherche avec un seul LONG au lieu de 4 BYTE est entre 2,3 et 2,4 fois plus rapide.
2/ il n'y a AUCUNE différence entre BYTE{ADD(position%,2)} et BYTE{position%+2}
3/ si on prévoit de faire tourner son programme sur une machine ayant de la FastRAM, penser à activer les bits TTRAM et Fastload smile

Et on pourrait aussi en déduire que :
- un Falcon030 est 3,86 fois plus rapide qu'un ST
- un Falcon060 avec TTRam activée est 14 fois plus rapide qu'un Falcon et 54 fois plus rapide qu'un ST

Bref, même en optimisant, 81 Ko/s sur un ST c'est pas terrible happy
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

10

t'as essayé avec ?

recherche1&=CVI('SN')
recherche2&=CVI('DH')
WHILE position% < maximum% 
    IF INT{position%}=recherche1&
        IF INT{ADD(position%,2)}=recherche2&
            ' traitement 
        END IF 
    END IF 
    ADD position%,2 
WEND 


D'autre part, j'ai jamais dit qu'un position%+2 était plus rapide qu'un ADD(position%,2).
C'est l'instruction (et pas la fonction) ADD position%,2 qui est plus rapide que position%=position%+2
Et emploie plutôt les INC, DEC, SUCC(), PRED() quand il s'agit de travail avec une unité 1, c'est plus élégant, et il me semble que c'est plus rapide qu'employer la valeur 1 (utilisation d'une constante, alors qu'on pourrait s'en passer).

Pour le travail en TTRAM, tu peux utiliser les Mxalloc = GEMDOS(68,L:...) avec les préférences pour allouer en TTRAM "de préférence", ça évite à l'utilisateur de se soucier des flags.

11

Rajah Lone :
t'as essayé avec ?

recherche1&=CVI('SN')
recherche2&=CVI('DH')
WHILE position% < maximum% 
    IF INT{position%}=recherche1&
        IF INT{ADD(position%,2)}=recherche2&
            ' traitement 
        END IF 
    END IF 
    ADD position%,2 
WEND 


Oui, les performances sont pratiquement identiques :
Steem 8 MHz : 11,02 s (ça consomme 1/2 s de plus)
Falcon030 16 couleurs : 2,75 s
FalconCT60, TTRam désactivée : 0,47 s
FalconCT60, TTRam activée : 0,165 s

Donc c'est un tout petit peu mieux avec de la TTRam mais moins bien avec un 68000.
Rajah Lone
grin'autre part, j'ai jamais dit qu'un position%+2 était plus rapide qu'un ADD(position%,2).
C'est l'instruction (et pas la fonction) ADD position%,2 qui est plus rapide que position%=position%+2


Oups, au temps pour moi, j'ai mal interprété tes propos smile

Et merci pour les conseils chinois
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

12

Strider :
Les deux premiers codes donnent les MEMES résultats, contrairement à ce que Rajah et moi croyions smile


Sauf erreur de lecture de ma part, les deux premiers codes sont IDENTIQUES smile c'est peut-être pour ça qu'ils donnent les MEMES résultats wink

Donc corriger dans le Code 1
ADD(position%,1) -> position%+1
ADD(position%,2) -> position%+2
ADD(position%,3) -> position%+3


A part ça je ne vois pas comment optimiser plus le code.
Gare à celui qui touche a mes chips quand je code !

13

Et cela :

for i%=position% to maximun%
    IF BYTE{i%}=90 AND BYTE{ADD(i%,1)}=80 AND BYTE{ADD(i%,2)}=70 AND BYTE{ADD(i%,3)}=60 
        ' traitement 
    END IF 
next i%


Je ne connais pas les temps de traitement du Gfa, c'est une idée qui vient de me passer par la tête, a premiere vue je dirais que c'est plus rapide car on profite de la boucle qui avance (Et c'est surement plus rapide) pour éviter l'add ou l'inc.

Et puis comme tu l'as supposé Strider, étant donné que c'est du code 68000, cela doit ètre aligné sur une adresse paire donc :

for i%=position% to maximun% step 4
    IF long(i%)=$xxxx
        ' traitement 
    END IF 
next i%



GT Turbo (C.V.S.D.) magic
avatar
Accrochez vous ca va être Cerebral !!

14

@GT Distrait : STEP 2, sinon on risque de passer à côté wink

@Stridounet : Je sais pas s'il faut indiquer une seule condition dans un IF ou toutes à la fois... Vu que ce sont des AND, on peut les imbriquer comme dans les exemples que je t'ai proposé.
Est-ce que le GFA ne teste plus les conditions suivantes si la première est FALSE ? Sinon, il va lire 3 BYTE{} pour rien si le premier ne commence pas par un 'S'. Ce serait dommage.

15

Rajah Lone :
@GT Distrait : STEP 2, sinon on risque de passer à côté wink


J'ai perdu un morceau ? On cherche bien 4 caractères non ? Car si la réponse est oui, tu va relire 2 octets pour rien avec un pas de 2

GT octopus
avatar
Accrochez vous ca va être Cerebral !!

16

Oui, on cherche 4 char/bytes, mais on ne sait pas à quelle adresse paire elle se trouve... paire = multiple de 2, pas de 4.
Si on fait 4, on risque de passer à côté, genre...

0 AA
2 SN
4 DH
6 BB
8 CC

Si on part de 0 et qu'on incrémente de 4 : on passe à côté. CQFD.

17

Exact merci pour la démonstration, Rajah.

GT En train de comprendre top
avatar
Accrochez vous ca va être Cerebral !!

18

for i%=position% to maximun%-2 step 2
    IF card(i%)=$xxxx
     If card(i%+2)!$yy    
    ' traitement 
    END IF 
  endif 
 next i%


Corrigé !!

octopus


avatar
Accrochez vous ca va être Cerebral !!

19

for i%=position% to maximun%-2 step 2


Petite précision ici : le maximum%-2 va être recalculté à chaque fois, et on perd du temps machine pour rien wink

Donc avant le for-next, SUB maximum%,2
et à après, on peut le remettre correctement avec un ADD maximum%,2

20

Dans ce cas, autant éviter d'utiliser {LONG} qui va chercher un mot long et lui préférer un {CARD} qui va chercher un mot (16 bits).
Codeur retraité coulant des jours paisibles...

Je raconte ma vie: http://blog.frosties.org/

21

Moi j'ai la soluce ultime :

  move.l #"SNDH",d0
Boucle:
  cmp.l (a0),d0                          (On pourrait faire le bricolage a coup de mot j'ai je crois que ca risque d'ètre encore plus lent !)
  beq.s Found
  addq.w #2,a0
  cmpa.l a1,a0
  blt.s Boucle
  jsr Pas_trouver

Found :
 traitement...



Avec a0=position% et a1=maximun%


GT dehors

P.S. : (J'en rajoute une couche) vu la taille du code cela rentre dans tous les caches existants !) top
Seconde couche : je peux meme te calculer la vitesse de traitement top
avatar
Accrochez vous ca va être Cerebral !!

22

Tu rulez GT ! top
Codeur retraité coulant des jours paisibles...

Je raconte ma vie: http://blog.frosties.org/

23

Bien vu GT oui

J'ai désassemblé le code GFA pour voir ce que ça donnait, mais c'est un tel merdier là-dedans que j'ai abandonné smile
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

24

On fait plus simple Strider, je t'assembles la routine, après il ne te reste plus qu'a faire un inline, elle te renverra dans d0, soit l'offset depuis position soi -1 si pas trouvé.

Et maintenant souvenir, l'appel devrait ètre un truc comme cela (Rectifier au cas ou mon Gfa se fait très vieux !) :

rcall find%,reg%()

en entrée reg%(0)=position%
reg%(1)=maximun%

et après appel

reg% (16)=offset ou -1

GT octopus
avatar
Accrochez vous ca va être Cerebral !!

25

Oui je veux bien, merci smile
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

26

On peut meme faire plus court, vu la taille du code on arrive a mettre la routine dans une chaine de caractères (60 octets au max). Je te prépares cela et t'envois dès que !!

GT octopus
avatar
Accrochez vous ca va être Cerebral !!

27

Merci GT Turbo ton code est bien plus rapide que celui pondu par le GFA happy

Sur un ST à 8 MHz :
* En GFA avec 2 CARD imbriqués : 10,58 s
* Et avec un LONG : 10,14 s
* La routine de GT Turbo : 2,65 s, soit une vitesse de traitement de 323,4 Ko/s (81 Ko/s pour le GFA)
(toujours avec le même fichier de 857 Ko contenant 23 SNDH)

Idem sur Falcon CT60, la routine de GT Turbo est 2 fois plus rapide qu'en GFA avec un LONG smile

avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

28

Sauf que c'est plutot un blo et pas un blt qu'il faut mettre
à la fin de la boucle: les adresses sont non signées...

Et salutations à tous! Ca faisait un bail que j'étais pas passé...

Seb

29

  cmpa.l a1,a0
  blt.s Boucle


GT : grin Seb fait référence à cet article (le site est à nouveau up) : http://removers.free.fr/spip/article.php?id_article=81 (pour résumer, le "blt.s Boucle" n'est pas correct pour a1 > 2 Go)
Stabylo/The Removers
http://removers.atari.org/

30

stabylo :
a1 > 2 Go


Je sais c'est pour cela que j'ai pas répondu !! top


GT Maxi a 256 !! magic
avatar
Accrochez vous ca va être Cerebral !!