Page 1 sur 2
lib memory
Publié : mer. 29/déc./2004 15:00
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.

Publié : ven. 31/déc./2004 10:19
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 ???
Publié : ven. 31/déc./2004 11:49
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à
Sinon, le
ProcedureReturn retourne la valeur dans eax (sauf pour les string), tu peux supprimer la dernière ligne
Tu pourrais aussi supprimer la ligne
et appeller la fonction comme ceci
berliozresult = CompareMem(source,dest,size)
Publié : ven. 31/déc./2004 12:37
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?
Publié : ven. 31/déc./2004 12:48
par Anonyme2
Non je ne connais pas. Faudrait jeter un oeuil dans la doc Intel.
Publié : ven. 31/déc./2004 13:16
par hardy
Ai trouvé (recherche web avec "mm0 opcodes" et trucs du genre). Je teste ça et te tiens au courant.
Publié : ven. 31/déc./2004 13:51
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))
Publié : ven. 31/déc./2004 14:11
par nico
Si tu pouvais créer une fonction de même type que findstring, ça m'intéresserait,.
Publié : ven. 31/déc./2004 14:18
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…
Publié : ven. 31/déc./2004 14:26
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?
Publié : ven. 31/déc./2004 15:43
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()
Publié : ven. 31/déc./2004 16:26
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 :
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
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
Publié : ven. 31/déc./2004 18:39
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 !

Publié : sam. 01/janv./2005 1:06
par hardy
D'abord bonne année !!!
@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.
Publié : sam. 01/janv./2005 18:22
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