Comment fseek () est-il implémenté dans le système de fichiers?

il ne s'agit pas d'une question de programmation pure, mais elle affecte la performance des programmes utilisant fseek(), il est donc important de savoir comment cela fonctionne. Un petit avertissement pour qu'il ne soit pas fermé.

je me demande à quel point il est efficace d'insérer des données au milieu du fichier. Supposons que j'ai un fichier avec des données de 1MB et que j'insère quelque chose au 512KB offset. Le degré d'efficacité serait-ce par rapport à l'ajout de mes données à la fin du fichier? Juste pour faire l'exemple complétez disons que je veux insérer 16KB de données.

je comprends que la réponse varie selon le système de fichiers, mais je suppose que les techniques utilisées dans les systèmes de fichiers courants sont assez similaires et je veux juste avoir la bonne notion de celle-ci.

16
demandé sur pajton 2010-03-13 18:52:50

6 réponses

(avertissement: je tiens juste à ajouter quelques conseils pour cette discussion intéressante) Il y a certaines choses à prendre en compte:

1) fseek n'est pas un service de système primaire, mais une fonction de bibliothèque. Pour évaluer sa performance, nous devons considérer comment la bibliothèque file stream est implémentée. En général, la bibliothèque d'e/s des fichiers ajoute une couche de tampon dans l'espace utilisateur, de sorte que les performances de fseek peuvent être très différentes si la position cible est à l'intérieur ou à l'extérieur de la zone tampon actuelle. En outre, les services de système que l'I/O libary utilise peuvent varier beaucoup. C'est-à-dire: sur certains systèmes, la bibliothèque utilise largement le mappage de mémoire de fichier si possible.

2) comme vous l'avez dit, différents systèmes de fichiers peuvent se comporter d'une manière très différente. En particulier, je m'attendrais à ce qu'un système de fichiers transactionnel fasse quelque chose de très intelligent et peut-être coûteux pour être préparé à un possible retour en arrière d'une opération d'écriture avortée au milieu d'un fichier.

3) les OS'e modernes ont une algorithmes de cache agressifs. Un fichier" fouillé " est probablement déjà présent dans le cache, donc les opérations deviennent beaucoup plus rapides. Mais ils peuvent se dégrader beaucoup si l'activité globale du système de fichiers produite par d'autres processus devient importante.

Tous les commentaires?

5
répondu Giuseppe Guerrini 2017-10-02 07:34:39

supposons le FS ext2 et L'OS Linux comme exemple. Je ne pense pas qu'il y aura une différence de performance significative entre un insert et un appendice. Dans les deux cas, le noeud de fichiers et la table d'offset doivent être lus, le secteur de disque concerné mappé dans la mémoire, les données mises à jour et à un point ultérieur les données écrites de nouveau sur le disque. Ce qui fera une grande différence de performance dans cet exemple est une bonne localisation temporelle et spatiale lors de l'accès à des parties du fichier car cela réduira le nombre de combinaisons charge/magasin.

comme une réponse précédente dit que vous pouvez être en mesure d'accélérer les deux opérations si vous traitez avec les données écrit que les multiples exacts de la taille de bloc FS, dans ce cas, vous pourriez sauter l'étape de charge et juste insérer les nouveaux blocs dans les fichiers inode datatructure. Cela ne serait pas pratique, car vous auriez besoin d'un accès de bas niveau au conducteur FS, et l'utiliser serait très restrictif et non portable.

4
répondu PinkyNoBrain 2018-05-26 03:39:58

fseek(...) est un appel de bibliothèque, pas un système d'appel. C'est la bibliothèque run-time qui prend en charge les frais généraux réels impliqués dans la réalisation d'un appel système à L'OS, techniquement parlant, fseek fait indirectement un appel au système mais ce n'est vraiment pas le cas (cela amène une distinction claire entre les différences entre un appel bibliothèque et un appel système). fseek(...) est une fonction d'entrée-sortie standard quel que soit le système sous-jacent...cependant...et c'est un grand toutefois...

il est plus que probable que le système d'exploitation ait mis le fichier en cache dans sa mémoire du noyau, c'est-à-dire le décalage direct par rapport à l'emplacement sur le disque sur lequel les 1 et 0 sont stockés, c'est-à-dire à travers les couches du noyau du système d'exploitation, plus que probable, une couche supérieure dans le noyau qui aurait l'instantané de la composition du fichier, c'est-à-dire des données indépendamment de ce qu'elles contiennent (cela ne fait aucun doute, aussi longtemps que les 'pointeurs' à la structure de disque pour cela décalage de l'emplacement sur le disque est valide!)...

Quand fseek(..) se produit, il y aurait beaucoup de Over-head, indirectement, le noyau a délégué la tâche de lire à partir du disque, selon la façon dont le fichier est fragmenté, il pourrait être théoriquement, "partout", qui pourrait être un over-head significatif en termes de devoir, d'un point de vue de l'utilisateur-terre, c.-à-d. le code C faire un fseek(...), il pourrait se disperser sur toute la place pour rassembler les données dans un " un contigu vue des données" et désormais, en insérant dans le milieu d'un fichier, (rappelez-vous à ce stade, le noyau devrait ajuster l'emplacement/offsets dans le plateau de disque réel pour les données) serait considérée plus lente que l'ajout à la fin du fichier.

la raison est très simple, le noyau "sait" ce qu'était le dernier offset, et il suffit d'effacer le marqueur EOF et d'insérer plus de données, en coulisses, le noyau, doit allouer un autre bloc de mémoire pour le Disk-buffer avec le décalage ajusté à l'emplacement sur le disque suivant un marqueur EOF, une fois que l'ajout des données est terminé.

2
répondu t0mm13b 2010-03-13 16:39:08

une observation que j'ai faite à propos defseek sur Solaris, est-ce que chaque appel à lui réinitialise le tampon de lecture du FILE. La prochaine lecture Lira alors toujours un bloc complet (8K par défaut). Donc, si vous avez beaucoup de l'accès aléatoire avec petit lit c'est une bonne idée de le faire sans tampon (setvbufNULL buffer) ou même utiliser des appels directs (lseek+read ou encore mieux pread qui est seulement 1 syscall au lieu de 2). Je suppose que ce comportement sera similaire sur d'autres OS.

2
répondu Patrick Schlüter 2010-08-29 18:48:11

vous pouvez insérer des données au milieu du fichier efficacement seulement si la taille des données est un multiple du secteur de FS mais OSes ne fournit pas de telles fonctions de sorte que vous devez utiliser l'interface de bas niveau pour le pilote de FS.

1
répondu Ha. 2010-03-13 16:03:39

insérer des données au milieu du fichier est moins efficace que l'ajout à la fin parce que lors de l'insertion vous devriez déplacer les données après le point d'insertion pour faire de la place pour les données étant insérées. Déplacer ces données impliquerait les lire à partir du disque, l'écriture des données à insérer et ensuite l'écriture des anciennes données après les données insérées. Vous avez donc au moins une lecture et une écriture supplémentaires lors de l'insertion.

1
répondu goedson 2010-03-13 16:31:25