lib memory

Programmation d'applications complexes
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

lib memory

Message par hardy »

Bon, je me suis remis à l'assembleur. Ca va, j'ai pas l'air trop rouillé (j'en avais pas fait depuis petit sur les ZX81 !!)
J'ai refait des fonctions du genre len, mid,... pour voir : à peu près même rapidité que celles de PB.
Je compte, pour mon usage personnel réaliser diverses procédures de manip de mémoire et autre (en ASM pour des raisons de rapidité). (ex : ROL sur une zone mémoire avec une longueur quelconque en bits, symétrisation bit à bit, test d'un bit donné,...)
J'invite donc ceux qui auraient des besoins particuliers dans le domaine de le faire savoir dans cette rubrique. Dans la mesure du possible (et de mon temps libre!), je les intégrerai.

Evidemment, si d'autres veulent participer à l'élaboration, ça n'en sera que mieux.
:D
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

Etrange : en codant diverses procédure, j'ai refait un comparemory comme celui de PB (et d'autres qui comparent selon l'ordre lexicographique,etc...)

pour le comparememory qui fait la même chose que celui de PB:

Code : Tout sélectionner

ProcedureDLL CompareMem(source,dest,size)
  Shared berliozresult
  n=size/4
  r=size-4*n
  MOV esi,source
  MOV edi,dest
  MOV ecx,n
  !MOV eax,1
  !boucle2:
  !MOV ebx,[esi]
  !MOV edx,[edi]
  !CMP ebx,edx
  !JNE diff
  !ADD esi,4
  !ADD edi,4
  !LOOP boucle2
  MOV ebx,r
  !CMP ebx,0
  !JE fin2
  MOV ecx,r
  !boucle3:
  !MOV bl,byte[edi]
  !MOV bh,byte[esi]
  !CMP bh,bl
  !JNE diff
  !INC edi
  !INC esi
  !LOOP boucle3
  !JMP fin2
  !diff:
  !MOV eax,0
  !fin2:
  !MOV [v_berliozresult],eax
  ProcedureReturn berliozresult
EndProcedure
Rien d'évolué. Pas d'astuce particulière.
verifié : elle marche

Mais elle est 3 à 4 fois plus rapide que la fonction PB.
Why?
Je me demande si la fonction PB lit les zones mémoires octets par octets, ce qui multiplierait effectivement par quatre les mouvements registres/mémoire.

FRED ???
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Tu as surement raison concernant, CompareMemoryString() retourne :
Le 'Texte1' est egal au 'Texte2'.
-1: Le 'Texte1' est inférieur au 'Texte2'.
1: Le 'Texte1' est supérieur au 'Texte2'
ce qui est typique d'une soustraction de 2 octets, un code de ce type là

Code : Tout sélectionner

  MOV cl, [eax]
  MOV ch, [edx]
  SUB   cl, ch
Sinon, le ProcedureReturn retourne la valeur dans eax (sauf pour les string), tu peux supprimer la dernière ligne

Code : Tout sélectionner

ProcedureReturn berliozresult 
Tu pourrais aussi supprimer la ligne

Code : Tout sélectionner

!MOV [v_berliozresult],eax 
et appeller la fonction comme ceci

berliozresult = CompareMem(source,dest,size)
Dernière modification par Anonyme2 le dim. 16/janv./2005 10:45, modifié 1 fois.
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

Oui, c'est un peu bête.

Pour le retour via eax, merci. Je ne savais pas quel registre utilise procedurereturn...

J'ai déjà codé des comparememory retournant -1,0, ou 1 en comparaison lexicographique par byte ou word ou long, en signé ou non.
Toutes sont plus rapides que le simple comparememory de PB.
Même raison, sans doute : je lis les données par 32 bits, et utilise des ROL pour les words et bytes.

Je vais coder un comparememorystring pour voir si plus rapide que la fonction PB.

Quand j'aurai avancé assez la lib je la mettrai à disposition.

Au passage : serait sans doute encore plus rapide par 64bits via les mm0,...
Connais-tu les fonctions rol, cmp,... pour ces registres?
Par exemple pour !mov, il faut utiliser !movq, !movntq.
!rolq,... peut-être?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Non je ne connais pas. Faudrait jeter un oeuil dans la doc Intel.
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

Ai trouvé (recherche web avec "mm0 opcodes" et trucs du genre). Je teste ça et te tiens au courant.
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

regarde ça:

Code : Tout sélectionner

mem=AllocateMemory(8)
PokeL(mem,$12345678)
PokeL(mem+4,$11020304)
mem2=AllocateMemory(4)
mem3=AllocateMemory(4)

MOV esi,mem
!movq mm0,[esi] ;move quadword (64 bits)
!movd ebx,mm0 ;mode dword (low)
;!pextrd ebx,mm0,0
MOV edi,mem2
!MOV [edi],ebx
!psrlq mm0,32 ;rightshift (quadpacked)
!movd ebx,mm0
MOV edi,mem3
!MOV [edi],ebx
Debug Hex(PeekL(mem2))
Debug Hex(PeekL(mem3))
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Si tu pouvais créer une fonction de même type que findstring, ça m'intéresserait,.
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message par Dräc »

hardy a écrit :J'invite donc ceux qui auraient des besoins particuliers dans le domaine de le faire savoir dans cette rubrique.
Puisque tu t’intéresses aux manipulations dans la mémoire : quel est selon toi la manière la plus rapide de mettre à zéro un tableau crée avec ‘Dim’?
Je suis loin d'y avoir réfléchi, mais j’ai en tete de faire une sorte de ‘CopyMemory’ d’une zone préalablement vierge vers le dit tableau…
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

D'abord comparememorystring sans MMX: (j'ai aps encore fait le cas case insensitive)

Code : Tout sélectionner

ProcedureDLL CompareMemString(source,dest,flag)
  Select flag
    Case 0 ; case sensitive
      MOV esi,source
      MOV edi,dest
      !MOV eax,0
      
      !bouclecms:
      !MOV ebx,[esi]
      !MOV edx,[edi]
     
      !CMP bl,0
      !JE fincms1
      !CMP dl,0
      !JE fincms2
      !CMP bl,dl
      !JA cmssup
      !JB cmsinf
      
      !CMP bh,0
      !JE fincms1h
      !CMP dh,0
      !JE fincms2h
      !CMP bh,dh
      !JA cmssup
      !JB cmsinf
      
      !ROL ebx,16
      !ROL edx,16
      
      !CMP bl,0
      !JE fincms1
      !CMP dl,0
      !JE fincms2
      !CMP bl,dl
      !JA cmssup
      !JB cmsinf
      
      !CMP bh,0
      !JE fincms1h
      !CMP dh,0
      !JE fincms2h
      !CMP bh,dh
      !JA cmssup
      !JB cmsinf
      
      !ADD esi,4
      !ADD edi,4
      
      !JMP bouclecms
      
      
      !fincms1:
      !CMP dl,0
      !JE fincms
      !MOV eax,-1
      !JMP fincms
      
      !fincms2:
      !CMP bl,0
      !JE fincms
      !MOV eax,1
      !JMP fincms
      
      !fincms1h:
      !CMP dh,0
      !JE fincms
      !MOV eax,-1
      !JMP fincms
      
      !fincms2h:
      !CMP bh,0
      !JE fincms
      !MOV eax,1
      !JMP fincms
      
      !cmssup:
      !MOV eax,1
      !JMP fincms
      
      !cmsinf:
      !MOV eax,-1
      
      !fincms:
      ProcedureReturn
      
    Case 1
      
  EndSelect
EndProcedure
Plus rapide d'un tiers environ que la fonction PB.
Je vais voir en mmx ce que ça donne.
Si tu pouvais créer une fonction de même type que findstring, ça m'intéresserait,.
c'est prévu (ainsi que des replacelong, replaceword, replacebyte)

Puisque tu t’intéresses aux manipulations dans la mémoire : quel est selon toi la manière la plus rapide de mettre à zéro un tableau crée avec ‘Dim’?
Mettre toutes les valeurs à zéro (dans ce cas un rtlzeromemory fait l'affaire), ou le redimensionner?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Voici une procedure prise sur le forum anglais pour la détection MMX
; English forum: http://purebasic.myforums.net/viewtopic ... highlight=
; El_Choni
; 26. Mai 2003

Code : Tout sélectionner

Procedure IsMMXSupported() ; Returns 8388608 if supported, 0 if not supported 
  result = 0 
  XOR EDX, EDX        ; Set edx to 0 just in case CPUID is disabled, not to get wrong results 
  MOV eax, 1          ; CPUID level 1 
  !CPUID              ; EDX = feature flag 
  AND edx, $800000    ; test bit 23 of feature flag 
  MOV result, edx     ; <>0 If MMX is supported 
  ProcedureReturn result 
EndProcedure 

Debug IsMMXSupported()
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Salut,
J'invite donc ceux qui auraient des besoins particuliers dans le domaine de le faire savoir dans cette rubrique. Dans la mesure du possible (et de mon temps libre!), je les intégrerai.
moi, il y a un truc qui m'intéresserait, c'est d'avoir une procedure d'inversion RGB vers BGR.

on peut le faire très simplement comme ça :

Code : Tout sélectionner

RGB(Blue(Couleur), Green(Couleur), Red(Couleur))
ou avec des PeekB, pokeB

Code : Tout sélectionner

Rouge.b = PeekB(@Couleur)
PokeB(@Couleur, PeekB(@Couleur + 2))
PokeB(@Couleur + 2, Rouge)
mais si il y a moyen d'optimiser :D

Voici un code pour tester la rapidité

Code : Tout sélectionner

#nb = 100000000 + 1

Couleur1.l = RGB(200, 100, 50)
Couleur2.l = RGB(200, 100, 50)

Temps1 = ElapsedMilliseconds()

For n = 1 To #nb
  Couleur1 = RGB(Blue(Couleur1), Green(Couleur1), Red(Couleur1))
Next

Temps2 = ElapsedMilliseconds()

For n = 1 To #nb
  Rouge.b = PeekB(@Couleur2)
  PokeB(@Couleur2, PeekB(@Couleur2 + 2))
  PokeB(@Couleur2 + 2, Rouge)
Next

Temps3 = ElapsedMilliseconds()

MessageRequester("Test rapidité", "Solution 1 : " + Str(Temps2 - Temps1) + " ; Solution 2 : " + Str(Temps3 - Temps2) + Chr(10) + "Couleur1 = RGB(" + Str(Red(Couleur1)) + ", " + Str(Green(Couleur1)) + ", " + Str(Blue(Couleur1)) + ")" + Chr(10) + "Couleur2 = RGB(" + Str(Red(Couleur2)) + ", " + Str(Green(Couleur2)) + ", " + Str(Blue(Couleur2)) + ")", 0)
mes 2 solutions sont sensiblement équivalentes en terme de rapidité

100 millions d'inversion en 3355ms pour la solution 1 et en 3194ms pour la solution 2 sur un 900mhz
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

fred devrai prendre Hardy dans son equipe de devellopement

du coup le purebasic va s'apeller "FASTBASIC" ou "TURBOBASIC"

ça a deja ete pris ?? bon temps pis ! :D
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

D'abord bonne année !!! :smilecolros:

@le soldat inconnu : j'intégrerai les conversions rgb/bgr, (ça ira plus vite) etc...
@denis : oui, je connais le code. déjà vu sur divers sites, dont intel.
Pour un maximum de compatibilité je vais faire sans mmx. J'ai testé : n'augmente pas considérablement la vitesse pour ce que je fais.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Tu pourrais jouter ZeroMemory et SwapMemory...
Meme si j'aimerais les voir en PB... Ce serait déjà mieux codé que ce que j'ai pondu...

http://purebasic.hmt-forum.com/viewtopic.php?t=2153

Dri
Répondre