Le projet avance 🙂

J'ai terminé la fonction de copie de fichier et bientôt celle qui copie les répertoires. Quant à Sherwood51, il s'occupe actuellement de l'interface graphique. On devrait donc prochainement arriver à une version "utilisable" du logiciel, je pense 😃

A ce moment là, on publiera déjà une alpha sur laquelle on ajoutera les fonctionnalités au fur et à mesure 😉
Super, j'ai hâte de tester l'alpha 🙂
Petite réflexion sur la vitesse des copies en général :
J'ai recopié des données d'un périphérique vers un autre et ai constaté une vitesse de transfert de l'ordre de X Mb/sec. Si, au lieu de lancer le transfert d'un répertoire unique, je transfère plusieurs répertoires les uns à la suite des autres, ma vitesse de transfert de l'ensemble (par addition des vitesses indiquées) est supérieure à ma vitesse X initiale, (et ce même si chaque transfert pris indépendamment est moindre). Il est donc plus efficace de lancer plusieurs transferts en // plutôt qu'un seul. L'autre avantage est qu'en cas d'arrêt pour poser une question stupide, le second transfert continue et tout le temps n'est pas perdu à attendre la réponse. Il me semble que le gain plafonne à 3 instances de copie simultanées.
Je ne sais pas si d'autres ont constaté cela, mais une option de parallèlisation des transferts pourrait être intéressante; à moins qu'il ne soit possible de booster la copie "unique" pour atteindre ces mêmes vitesses 😉
Qu'en pensez-vous ?
BD
5 jours plus tard
Je reviens à la charge; c'est un sujet qui m'intéresse beaucoup !
Il serait aussi très pratique d'avoir tous les détails des fichiers en cas de duplicatas. En général, le copieur dit qu'une instance du fichier existe déjà dans la destination, mais sans en dire beaucoup plus. Faut aller voir avec le gestionnaire de fichiers les dates, tailles, différences entre les deux. Ce serait génial si ces infos apparaissaient directement : nom de fichier, taille (précises), date de création, dernier accès, propriétaire... et pourquoi pas un md5sum pour comparer les deux ? Pour ne pas réinventer le fil à couper le beurre, un couplage avec fslint ou équivalent... ?
Merci !
BD
Brunod a écritIl me semble que le gain plafonne à 3 instances de copie simultanées.
Je suis arrivé à la même conclusion 😃 Surtout qu'avec les processeurs multicoeurs d'aujourd'hui, cette parallélisation de la copie est plus qu'intéressante.
Brunod a écrità moins qu'il ne soit possible de booster la copie "unique" pour atteindre ces mêmes vitesses
Je ne pense pas, mais rien n'empêche de booster la copie et de lancer plusieurs copies simultanées 😃
Brunod a écritIl serait aussi très pratique d'avoir tous les détails des fichiers en cas de duplicatas. En général, le copieur dit qu'une instance du fichier existe déjà dans la destination, mais sans en dire beaucoup plus.
Je suis d'accord, j'ai souvent été confronté à ce genre de situation et c'est franchement pénible.
Brunod a écritet pourquoi pas un md5sum pour comparer les deux ? Pour ne pas réinventer le fil à couper le beurre, un couplage avec fslint ou équivalent... ?
Est-ce que le md5sum est vraiment utile dans ce cas là ? On pourrait simplement vérifier la taille du fichier ainsi que sa date de dernière modification, qu'en penses-tu ?

Je pense que la md5sum pourrait être intéressante pour vérifier si tous les fichiers ont été bien copiés. Mais en option, parce que ce n'est pas forcément utile pour toutes les copies.
Non je ne pense pas que le md5sum soit utile pour tester toutes les copies; ça ralentirait beaucoup trop. Mais c'est utile pour savoir si deux fichiers sont semblables ou non lorsque tout le reste est semblable par ailleurs : taille, date création...
😉
BD
Brunod a écritNon je ne pense pas que le md5sum soit utile pour tester toutes les copies;
C'est pour ça que je parlais d'option. Pour certaines copies très sensibles ça peut être important de s'assurer qu'il n'y ait eu aucune perte.
Brunod a écritMais c'est utile pour savoir si deux fichiers sont semblables
Oui mais en fin de compte est-ce que ça a un intérêt ? Qu'est-ce que ça apporterait de savoir si les deux fichiers sont différents ? Si on a la taille, la date de création et la date de dernière modification, ça permet déjà de vérifier s'ils sont identiques et aussi de choisir lequel des deux fichiers on veut garder. En plus, sur les très gros fichiers, ce serait long et ça ralentirait un peu tout. Imagine un peu qu'il y ait un certain nombre de gros fichiers portant le même nom...
Ou de renommer et garder les deux ! Des photos dont les infos seraient semblables alors que tout le reste est semblable, je préfère les repérer sans choisir que l'une écrase l'autre.
Mais je répète, ce ne serait à faire QUE si tout le reste concorde, et c'est assez exceptionnel tu sais, que tout le reste concorde. Mais j'ai déjà eu le cas.
Brunod a écritOu de renommer et garder les deux
Oui bien sûr 😉
Brunod a écritMais je répète, ce ne serait à faire QUE si tout le reste concorde
Oui d'accord si ce n'est QUE si tout le reste concordre, sinon ce serait un peu lourd 😃
On s'est rejoint ! 🙂
8 jours plus tard
Salut,

on manque cruellement de temps en ce moment (études universitaires + boulot) :/
J'espère que l'on trouvera le temps de bien avancer pendant ces vacances de noël.

Pour donner une info quand même, Revan a comparé le moteur de copie de LC et celui de cp. Résultat: soit a égalité soit plus performant.
L'idée (piquée à NetBSD) de maper en mémoire les fichiers de moins de 8mb se révèle diablement efficace sur les petits fichiers 🙂
De tout cœur avec vous 🙂
Mais impatient quand même ! 😛
BD
🙂
ça fait sacrément plaisir des encouragements pareils 😉

d'ailleurs, je passe le message: on aurait besoin de quelqu'un pour faire le GUI en GTK. Enfin besoin... c'est juste que cela nous permettrait d'avancer un peu plus vite. J'ai commencé à faire quelque chose mais depuis je me concentre sur l'interface de la version console tandis que Revan s'occupe du moteur de copie. Sinon je m'y remettrais mais... GTK c'est pas mon fort.

Car en fait, on a décidé de faire une version console et une version GTK. D'abord, la console c'était pour tester le moteur de copie puis on s'est dit que ça serait quand même vachement pratique si, par exemple, on veut faire des copies massives sur son serveur en étant connecté en SSH. Ou bien tout simplement si on est allergique aux interfaces graphiques... 😛
@Brunod, @Revan... discussion intéressante sur les "performances" maximales !

Mais en réalité il n'y a pas de "meilleur" truc, tout dépend du "use case" (cas d'utilisation), notamment son matériel et ce qui est le "maillon faible".

J'avais réalisé un moteur de copie optimisé sur CTOS (un O.S. hélas disparu)... il y a une vingtaine d'années !.. Et pour le "use case" à l'époque c'était fort intéressant par rapport à la copie basique du système.

Que se passe-t-il dans un programme de copie "naïf" (comme celui de Windows... et d'où l'intérêt de SC sur Windows), lorsqu'on copie un fichier :
Début :
- Lecture bloc fichier source
- Ecriture bloc fichier destination
=> tant qu'il reste des octets à écrire, retourner à début.
... et voila ! Ça s'appelle de la copie en série. Et c'est raisonnablement efficace dans 90% des cas où on copie un fichier d'un disque sur lui-même.
Simplement ce même algorithme s'avère largement sous-optimisé lorsqu'on copie entre plusieurs périphériques différents : disque à disque, disque à clé USB, disque à disque via réseau, etc...

Pour comprendre pourquoi il faut descendre au niveau physique de la chose.

Commençons par le cas simple :

- Copie d'un fichier d'un disque physique sur lui-même :
On suppose qu'il s'agit là d'un disque physique magnétique avec des plateaux et des têtes de lecture.
L'opération de copie va donc nécessiter de déplacer la tête à l'endroit à lire, lire un bloc, déplacer la tête à l'endroit à écrire, écrire un bloc, etc... jusqu'à ce qu'on ait fini la copie.
Le temps CPU est négligeable (une boucle simple, et des DMA pour lire/écrire) et donc le "maillon faible" en l'occurrence est le disque physique qui va devoir lire/écrire et déplacer les têtes.
Les optimisations que l'on peut faire dépendent de la taille des fichiers.
Sur les gros fichiers, il n'y a pas grand chose à faire en réalité.
Le temps de copie peut se calculer assez simplement à partir du temps d'accès moyen de déplacement des têtes et des vitesses moyennes de lecture/écriture des données.
Comme la taille des données à lire et à écrire est constante pour une copie donnée, le seul facteur de gain est donc de diminuer le nombre de déplacement de têtes, c'est à dire d'augmenter la taille du buffer de copie.
La seule optimisation plus "fine" serait d'essayer de "placer" le fichier destination au plus près du fichier source sur le disque pour limiter le déplacement des têtes. Mais là on est plutôt dans une optimisation de filesystem que dans une optimisation du niveau d'un "copieur".
On aura aussi des résultat assez différents selon la "fragmentation" qui génère inévitablement des déplacements de tête même si le fichier est tout lu/écrit en mémoire.

Sur les petits fichiers, il y a probablement une taille optimale de buffer et de regroupement, mais elle dépend probablement du type de formatage. En effet la lecture et l'écriture de plusieurs petits fichiers va générer des I/O supplémentaires pour aller lire les structures de contrôles du disque.

Notons que dans ce cas la parallélisation est contre-productive ! En effet, supposons que je coupe mon gros fichier en deux et fasse la copie des deux parties en parallèle, eh bien je vais générer tout un tas de déplacement de têtes qui sont préjudiciable à la rapidité de la copie.
Pour vous en convaincre c'est très simple.
- Ouvrez un terminal
- Lancez une copie d'un gros fichier (3 ou 4Go par exemple) et chronométrez.
- Une fois la première copie finie, lancez une copie d'un autre gros fichier et chronométrez.
- Ajoutez les deux temps.
- Supprimez vos deux copies.
- Refaites maintenant la même chose avec deux fenêtres de terminal ouvertes en même temps et en faisant les deux copies au même moment, chronométrez.
- Vous devriez observer un temps notablement supérieur au premier chrono (je suppose bien sûr que les copies sont toutes sur le même disque physique, et que votre disque dispose de suffisamment d'espace pour qu'une fragmentation excessive ne casse pas tout !)

Conclusion de ce use-case : un "SuperCopieur" ne fait quasiment rien gagner par rapport à la copie système classique (éventuel gain sur une copie de multiple de petits fichiers... mais pas sûr que du rsync ou des utilitaires standards ne fassent pas jeu égal voire mieux dans ce cas là !)

Cas plus intéressant
- Copie d'un fichier d'un disque physique sur un autre support physique :
Là c'est nettement plus amusant.
On a maintenant 3 facteurs :
- Vitesse de lecture
- Vitesse de transfert des données
- Vitesse d'écriture
Et là, les programmes de copie optimisés ont un avantage... à condition qu'ils parallélisent (comme vous l'avez observé).
La vitesse que l'on peut obtenir va dépendre du "maillon faible".
Supposons que mes deux supports physiques soient sur deux machines séparées par un réseau local.
Dans ce cas, le "maillon faible" pourra être le réseau local.
Un disque dur moyen sait lire/écrire entre 50 et 150MB/sec.
Si vous êtes sur un réseau local en 100Mbps, la vitesse maximale théorique est de 12,5MB/s et en pratique on plafonne autour de 11,5MB/s en NFS (le plus efficace) une fois retiré les overhead protocolaires.

Par conséquent, dans ce cas : copie d'un disque 1 à un disque 2 au travers d'un réseau à 100Mbps, votre vitesse maxi est la vitesse du réseau.

Or un programme de copie classique "série" perd du temps.
En effet, dans ma "boucle" naïve ci-dessus,
- je lis un bloc (et j'attends qu'il soit lu)
- ensuite je l'écris (ce qui nécessite au préalable de le transférer).
... puis je boucle.

J'ai donc :
- Temps lecture d'un bloc
- Temps de transfert
- Temps d'écriture d'un bloc
multiplié par le nombre de blocs.

Donc très exactement, on ajoute les 3 temps : lecture, écriture, transfert.

Finalement tout ceci est assez nigaud lorsqu'on considère que dans ce cas là les périphériques sont indépendants et pourraient lire et écrire en parallèle. Le réseau étant aussi indépendant du disque, il est possible de transférer le bloc N pendant que je lis le bloc N+1.

Un programme de copie optimisé devra donc dans ce cas :
- Allouer "un certain nombre" de blocs (mais pas trop gros... c'est contre-productif)
- Lire de façon "asynchrone" le fichier source dans les blocs
- Dès qu'un bloc de lecture est totalement rempli, on l'envoie à l'écriture.
- Lorsqu'une écriture est finie, on libère le bloc pour le rendre au process de lecture.

Pourquoi pas des "gros blocs". A l'extrême si j'ai suffisamment de mémoire pour lire tout mon fichier source en RAM et que je fais ainsi, je vais retomber dans le cas précédent de cumul des temps et on ne va pas paralléliser du tout !..

Alors ceci est la théorie, et c'était très utile sur CTOS (le gain de temps était manifeste) et toujours utile sur Windows.

Sur Linux c'est beaucoup moins utile... Pourquoi ?.. Eh bien parce que Linux est bien mieux que Windows et dispose de "buffers" considérables pour les copies.
C'est potentiellement différent d'un système à l'autre, mais sur mes PC à 4G de RAM (assez standard maintenant) j'observe un buffer de 256MB.

Pour l'observer c'est assez simple : faites une copie d'un gros fichier (par ex. 1GB) d'un disque à une clé USB. Vous allez voir les premiers 256MB se copier à toute vitesse -en réalité à la vitesse de lecture de votre disque qui est en général bien plus rapide que votre clé USB-, et ensuite le machin ralentit considérablement.
Pourquoi : tout simplement quand le système vous dit que les premiers 256MB sont copiés en réalité ils ne le sont pas réellement, ils sont juste dans le buffer de copie !.. D'ailleurs à la fin de la copie vous verrez le système "coincé" plusieurs secondes autour de 100%, c'est le temps de vidage du buffer.
Donc en réalité ce gros "buffer" joue tout à fait son rôle de parallélisation et on gagne assez marginalement à en rajouter.


Conclusion finale... "hélas" pour votre projet, Linux est tellement bien fait qu'il y a bien moins à grapiller en performances que sur des systèmes Windows avec un "SuperCopier" !..


... et c'est sûr aussi il n'y a pas que les performances, on peut certainement apporter des améliorations ergonomiques à la copie, notamment la possibilité de la mettre en pause si on a un truc urgent à faire, une grosse copie ayant tendance à sérieusement ralentir un système qui chercherait à faire des I/O sur le même disque.
Sherwood51 a écrit🙂
...
Car en fait, on a décidé de faire une version console et une version GTK. D'abord, la console c'était pour tester le moteur de copie puis on s'est dit que ça serait quand même vachement pratique si, par exemple, on veut faire des copies massives sur son serveur en étant connecté en SSH. Ou bien tout simplement si on est allergique aux interfaces graphiques... 😛
YES ! C'est Noël avant Saint Nicolas ! :')
Avec scp ?
Linux (grâce à sa communauté) est grand !
@Zakhar :
Rien que l'aspect ergonomique de ne plus devoir attendre stupidement une réponse après le troisième fichier lorsqu'il en reste 50000 à copier est déjà un gain extra ordinaire 😉
Et ça, à ma connaissance, sur Linux non plus ça n'existait pas.
Zakhar a écrit Conclusion finale... "hélas" pour votre projet, Linux est tellement bien fait qu'il y a bien moins à grapiller en performances que sur des systèmes Windows avec un "SuperCopier" !..
... et c'est sûr aussi il n'y a pas que les performances, on peut certainement apporter des améliorations ergonomiques à la copie, notamment la possibilité de la mettre en pause si on a un truc urgent à faire, une grosse copie ayant tendance à sérieusement ralentir un système qui chercherait à faire des I/O sur le même disque.
Merci pour ta superbe "explication de texte", vraiment bien détaillée tout en restant compréhensible, respect ! 🙂

Même si le gain en perf sera mini (ce que j'ai appris graçe à toi), il y a gros à gagner en terme d'ergonomie et de convivialité dans le cas de copies multiples de fichiers, LinCopier n'est donc pas un projet à abandonner pour autant.

😉