boursicotteur
Messages postés
201
Date d'inscription
mercredi 25 septembre 2002
Statut
Membre
Dernière intervention
10 novembre 2007
28 sept. 2007 à 23:24
Désolé pour ma lenteur à répondre...
Mon fournisseur internet était down...
### INTERPRÉTATION DES TEMPS ###
Les résultats de mes tests sont "moyennement" fiable pour 2 raisons:
1-Je mesure avec l'API GetTickCount (précision 1 mSec).
J'échantillonne l'horloge immédiatement AVANT et APRÈS ta fonction. La différence de ces 2 valeurs est cumulée à chaque passage de boucle et cela me donne une valeur totale. Ta fonction est plus rapide que la précision de GetTickCount et je multiplie cela par un gros chiffre alors je suis surpris d'avoir des résultats pas plus variables.
2 Mon ordi manque de RAM. Chaque fois qu'il sauvegarde sur le disque dur des choses (pas requises dans l'immédiat) pour libérer du RAM requis immédiatement, cela ralentie le déroulement du prog...et par conséquent augmente mes temps de lecture.
Il faut donc les interpréter comme une tendance seulement.
### FONCTION 16 BITS ###
Elle semble aussi rapide qu'avant.
Cette fois-ci j'ai obtenu 731mSec (moy de 8 valeurs de 666 à 816)
Mais faut préciser que ce 731 (temps d'extraction) est la somme de 2 temps:
Celui de ta DLL et celui d'une ligne de code VB (que je croyais insignifiante)
J'ai testé pour voir la part de chacun:
329 mSec pour ta DLL
402 mSec pour ma ligne de code VB
Ce 329 mSec est le temps pris pour extraire 43677 fois (5,590,602/128) les Min et Max parmis 128 nombres.
C'est à peine 7.53 uSec par extraction!
Pour moi c'est assez optimisé... BRAVO!
### FONCTION 8 BITS ###
Cette fois-ci elle fonctionne à la perfection. BRAVO!
J'ai testé avec un fichier (1 canal 8 bits) de 6,463,972 échantillons. Ta fonction a donc traité 50,500 segments de 128 échantillons.
Le temps pris (par elle seule) est:
438 mSec (moy de 8 tests 380 à 492)
C'est 8.68 uSec par extraction
C'est 15% de plus que l'autre fonction mais c'est peut-être dû au format BYTE car les processeurs ne traitent pas tous les formats à la même vitesse...
J'ai entendu dire que le format le plus rapide est LONG.
### FINALISATION DES 2 FONCTIONS ###
1- A mon avis, la fonction 16 bits est suffisamment performante mais c'est toi qui décides.
2- Pour la fonction 8 bits moins rapide, faudrait voir si c'est à cause du format BYTE ou de l'algorythme et prendre une décision en conséquence.
Moi je peux très bien vivre avec 8.68 uSec.
3- J'aimerais ajouter une dernière variable de sortie à ta fonction. Il s'agit de l'amplitude maximale Amax calculée par la ligne de code chronométrée avec ta fonction et qui bouffe plus de temps qu'elle.
Pour la fonction 16 bits ma ligne de code est:
Amax = IIf(Abs(xMin) < Abs(xMax), Abs(xMax), Abs(xMin))
Pour la fonction 8bits ma ligne de code est:
Amax = IIf(Abs(xMin - 128) < Abs(xMax - 128), Abs(xMax - 128), Abs(xMin - 128))
4- Pour rendre ces 2 fonctions aussi flexibles que possible (et utilisables par mon prog), il reste à utiliser un tableau à 2 dimentions et à ajouter les 2 variables permettant de pointer sur le canal et sur le début du bloc.
5- Pour faciliter l'usage de tes fonctions et leur donner une apparence aussi prêt que possible des fonctions du commerce, j'aimerais te suggérer ce format ci:
Amax= bnGetInt16MinMax (
ByRef pTab As Integer,
By? pDimA As long
By? pDimB As long
ByVal nElems As Long,
ByRef outMin As Integer
ByRef outMax As Integer
) As Integer
Amax= bnGetByteMinMax(
ByRef pTab As Byte
By? pDimA As long
By? pDimB As long
ByVal nElems As Long,
ByRef outMin As Byte
ByRef outMax As Byte
) As Byte
Amax est la valeur maximale de l'amplitude dans le bloc.
Cette valeur étant "dédiée à ma seule application", j'ai pensé qu'il serait préférable de la transmettre de cette façon pour préserver l'aspect "général" de ta fonction qui sera utilisée par beaucoup de personnes et à bien des sauces.
pTab pointe sur un tableau à 2 dimentions T(A, B) où
"A" référence les canaux
"B" référence les échantillons
pDimA pointe sur le canal (0,1, ...) dont on veux extraire Min et Max
pDimB pointe sur l'échantillon où débute le bloc à examiner (actuellement elle débute toujours à 0)
nElems est la grosseur du bloc à examiner
outMin est la valeur minimale trouvée dans le bloc
outMax est la valeur maximale trouvée dans le bloc
### BYPASSER LE TABLEAU ###
J'ai lancé cette idée en rêvant un peu tout haut et sans vraiment savoir de quoi je parlais car je suis ici à la frontière de mes connaissances.
Je peux me tromper (tant mieux si c'est le cas) mais après réflexion, je ne suis pas certain que cela va épargner temps et RAM. Je m'explique...
Actuellement, je dois:
1- Mettre le fichier wave en mémoire virtielle et obtenir son handle avec l'API
hFile = CreateFile(vFilePath, GENERIC_READ, FILE_SHARE_READ, 0&, OPEN_EXISTING, 0&, 0&)
2- Pointer sur le début du data dans le fichier virtuel avec l'API
SetFilePointer hFile, vFileOffset, 0&, FILE_BEGIN
3- Remplir le tableau avec un segment de 128 échantillons avec l'API
ReadFile hFile, T16(0), vFileBlocs * 128, Ret, 0&
Cela me donne le tableau que ta DLL traite.
## 1ère Question ##
Est-ce que ces API seront plus rapide si c'est C++ qui appelle au lieu de VB?
=> Moi je crois que non alors pas profitable de mettre cela dans la fonction.
## 2è Question ##
Est-ce que te donner un handle au lieu d'un tableau va épargner temps et RAM?
Oui...si tu es capable de comparer des nombres RAPIDEMENT sans devoir passer par la mémoire RAM.
À mon avis, c'est très loin d'être gagné car les obstacles sont nombreux:
1- Dans le fichier virtuel, tout est en octet alors pour avoir un INTEGER il faut aller chercher les 2 octets qui le compose et les fusionner correctement.
2- Chaque lecture du fichier virtuel prend un certain temps qui croît moins rapidement (enfin je crois) que la grosseur du bloc lu. Si j'ai raison alors il y a grand intérêt à lire par gros bloc plutôt que par petit bloc. Or, pour comparer des nombres dans la mémoire virtuelle, il faudra (sauf erreur) lire par très petits blocs.
etc