jockos
Messages postés321Date d'inscriptiondimanche 22 octobre 2000StatutMembreDernière intervention14 mai 2005
-
16 févr. 2004 à 12:09
RodrigueC
Messages postés2Date d'inscriptionlundi 9 juin 2003StatutMembreDernière intervention27 août 2007
-
28 mai 2007 à 18:47
Bonjour,
Je développe un logiciel de cryptage.
Mon logiciel doit pouvoir crypter de très gros fichier (plusieurs centaines de Mo).
Je monte le fichier en mémoire block par block (1 bloc = 64 Ko par exemple) et crypte donc block par block en mémoire pour ensuite redescendre le block crypté dans le fichier de destination.
C'est très rapide jusqu'à des fichiers de 120 Mo (environ 3 secondes), mais au dessus de 120 Mo, ça devient très long (20 secondes environ).
J'ai 256 Mo de RAM...
J'utilise un buffer (unsigned char *) pour stocker mes blocs.
J'ai essayé avec les API ReadFile et WriteFile et aussi avec les fonctions C++ fread et fwrite et j'obtiens toujours le même résultat.
Le problème vient donc de Windows.
Il doit s'embrouiller dans le Swap ou je ne sais pas quoi...
C'est assez déroutant...
120 Mo --> très rapide
130 Mo --> très lent
jockos
Messages postés321Date d'inscriptiondimanche 22 octobre 2000StatutMembreDernière intervention14 mai 20052 16 févr. 2004 à 12:18
Pour infos, j'utilise Windows XP.
A chaque fois, il est plus lent au 1er traitement du fichier.
Quand je retraite le même dichier, il va beaucoup plus vite à partir de la 2ème fois.
Pour les fichiers très gros (200Mo), il arrive qu'il aille très vite (2, 3 secondes, comme pour le fichier de 120Mo) et puis d'un seul coup, il va mettre 20 secondes...
Comment booster Windows pour le rendre performant sur chaque traitement d'ouverture et de sauvegarde du block, car le problème de performance semble venir uniquement de la gestoin mémoire faite par Windows.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 16 févr. 2004 à 12:22
Tu devrais utiliser des blocs d'un mo, ce serait mieux.
Je te conseille d'utiliser ReadFile pour la lecture et HeapAlloc pour l'allocation de mémoire.
Pour ton problème, j'èspère que tu ne fais l'allocation qu'un fois, sinon ton pb à partir de 130mo est très bizarre.
Tu pourrais peut être mettre ton code pour voir?
jockos
Messages postés321Date d'inscriptiondimanche 22 octobre 2000StatutMembreDernière intervention14 mai 20052 16 févr. 2004 à 14:44
Voilà mon code...
Pour simplifier, il ne traite pas le cas ou le dernier bloc à charger en mémoire a une taille inferieur à la taille d'un bloc.
Par exemple, pour un fichier de 200 Ko, sachant qu'un bloc fais 64Ko, je vais faire :
Bloc 1 : 64 Ko
Bloc 2 : 64 Ko
Bloc 3 : 64 Ko
Bloc 4 : 64 Ko (au lieu de 8 Ko)
////////////////////////////////////////////////////////////////////
#define BLOC_SIZE 64 //taille d'un bloc en Ko
bool OpenFileByBloc (char * filename)
{
HANDLE hFile, hHeap;
LPVOID pBloc; //pointeur sur le buffer contenant les blocs
DWORD lengthFile; //taille totale du fichier (en octets)
DWORD lengthBloc; //taille d'un bloc (en octets)
/* création du handle sur le fichier à ouvrir */
hFile = CreateFile (filename,
GENERIC_READ, 0, 0,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
/* taille en octets du fichier à ouvrir */
lengthFile = GetFileSize (hFile, 0);
/* taille en octets du buffer */
lengthBloc = BLOC_SIZE * 1024;
/* allocation mémoire du buffer recevant les blocs du fichier */
hHeap = GetProcessHeap();
pBloc = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, lengthBloc);
if (pBloc == NULL) return FALSE;
/* position du curseur dans le fichier (position du bloc à traiter) */
DWORD i = 0;
/* nombre d'octets lu par ReadFile */
DWORD lengthRead = 0;
/********************************************/
while (i < lengthFile)
{
/* place le curseur sur le bloc à monter en mémoire */
SetFilePointer (hFile, i, 0, FILE_BEGIN);
/* charge le morceau du fichier en mémoire dans le bloc "pBloc" */
ReadFile (hFile, pBloc, lengthBloc, &lengthRead, 0);
/* passe au bloc suivant */
i = i + lengthBloc;
}
/********************************************/
/* libère le buffer */
HeapFree (hHeap, 0, pBloc);
/* ferme le fichier */
CloseHandle (hFile);
return TRUE;
}
Vous n’avez pas trouvé la réponse que vous recherchez ?
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 16 févr. 2004 à 15:01
oh pardon tu as posté ton code entre temps
pour ton problème je dirais que c'est normal qu'il mettent longtemps pour les gros fichier, même si c'est bizarre qu'il saute brusquement vers 120mo, en tous cas je ne vois pas pq ce serait un pb de ram, puisque tu n'utilises en tout et pour tout que 64ko.
J'ai essayé chez moi et il met environ 35s pour 700mo (mais avec des blocs de 1mo)
ymca2003
Messages postés2070Date d'inscriptionmardi 22 avril 2003StatutMembreDernière intervention 3 juillet 20067 17 févr. 2004 à 00:25
Je pense que lorsque tu lit un fichier, windows le garde dans un coin de la mémoire (pour pouvoir y accéder plus rapidement par la suite). C'est pour cela qu'au 2ème traitement c'est plus rapide. La rupture doit provenir du fait que la limite de stockage rapide est atteinte.
jockos
Messages postés321Date d'inscriptiondimanche 22 octobre 2000StatutMembreDernière intervention14 mai 20052 17 févr. 2004 à 10:11
Je pense que tu dois avoir raison...
Mais il doit forcément y avoir une solution pour remédier à ce problème...
Il y a des options pour l'API CreateFile... au niveau du flag (là ou j'ai mis FILE_FLAG_SEQUENTIAL_SCAN)... On peut mettre NO_BUFFERING...
Cependant, j'ai essayé et ça ne change pas grand chose...
Roroapprieu
Messages postés1Date d'inscriptionmercredi 10 novembre 2004StatutMembreDernière intervention18 août 2005 18 août 2005 à 10:27
Je pense que le problème est plus complexe que cela. J'utiliserais non pas l'aloocation sur le Tas ( HeapAlloc ) mais GlobalAlloc. Je pnse que la taille du swapfile est à prendre en considération. Il ne faut pas perdre de vue que windows "adrore" utiliser le swap en liaison avec la RAM. J'ai copire et gérer ton code sans l'alocation de mémoire en créant un fichier mapper en mémoire accessible par un pointeur de caractéres. Je n'ai pas du tout ces là pour un gros fichier 1Go. Par contre j'ai un swap fixe de 3Go sur un disque indépendant (physiquement de mon disque de dev) et j'ai 1Go de RAM. Je divice les temps par 3 environ. Je peux si tu le désires t'envoyer ce bout de code. (jean_bezet@tele2.fr).
RodrigueC
Messages postés2Date d'inscriptionlundi 9 juin 2003StatutMembreDernière intervention27 août 2007 28 mai 2007 à 18:47
Je sais que ce message date de très longtemps mais tu devrais essayer de réserver de la mémoire SWAP avant de faire ton traitement. Regarde sur msdn...
La première fois ton traitement est très lent car il faut le temps d'allouer toutes les pages nécessaires au traitement de tes blocs de données. La seconde fois, ces pages sont déjà toutes allouées au sein du gestionnaire de Windows c'est pourquoi le traitement est beaucoup plus rapide. Il existe une fonction pour allouer plusieurs pages d'un coup!