Comment paralléliser fichier en lecture et en écriture
J'ai un programme qui lit les données à partir de 2 fichiers texte, puis enregistrer le résultat dans un autre fichier. Car il y a beaucoup de données qui peuvent être lues et écrites qui cause une dégradation des performances, je veux parallize la lecture et de l'écriture des opérations.
Ma première pensée est, utiliser 2 fils comme un exemple, un thread de lecture/écriture depuis le début, et un autre thread de lecture/écriture à partir du milieu du fichier. Depuis mes fichiers sont formatés comme des lignes, et ne octets(chaque ligne peut avoir différents octets de données), de chercher, par octet ne fonctionne pas pour moi. Et la solution, je pense utiliser getline() pour sauter les lignes précédentes en premier, ce qui peut ne pas être efficace.
Est-il une bonne façon de rechercher une ligne spécifiée dans un fichier? ou avez-vous d'autres idées pour parallize fichier en lecture et en écriture?
Environnement: Win32, C++, NTFS, Disque Dur
Grâce.
-Dbger
est-ce que cela signifie parallize disk I/O aura toujours causer une dégradation des performances si seulement lecture/écriture sur le même disque?
Dbger: Si vous utilisez un disque dur, oui.
si vous traitez des fichiers, vous pouvez envisager de chevauchement des I/O et le calcul. Si vous voulez vraiment essayer parallèle, vous pouvez diviser vos fichiers en segments (logiquement), demander à ce segment, trouver en début de ligne dans le segment, et de lire jusqu'à ce segment suivant.
Je ne sais pas beaucoup au sujet de "diviser des fichiers en plusieurs segments", mais si le disque I/O préfère accès séquentiel, la segmentation appraoch travail?
OriginalL'auteur Baiyan Huang | 2010-01-03
Vous devez vous connecter pour publier un commentaire.
En général, vous ne voulez PAS pour paralléliser les e/s de disque disques Durs n'aiment pas aléatoire I/O, car ils ont à chercher en permanence autour pour obtenir les données. En supposant que vous n'utilisez pas de RAID, et que vous utilisez des disques durs plutôt que d'une mémoire ssd, vous verrez une grave dégradation des performances si vous paralléliser les I/O(même lors de l'utilisation de technologies comme ceux-ci, vous pouvez encore voir quelques une dégradation des performances lorsque vous faites beaucoup d'aléatoire I/O).
Pour répondre à votre deuxième question, il n'y a vraiment pas une bonne façon de rechercher une certaine ligne dans un fichier; vous ne pouvez cherchent explicitement à un décalage d'octet à l'aide de la
read
fonction(voir cette page pour plus de détails sur la façon de l'utiliser.Oui, de recherche sur disque, le temps sera généralement le goulot d'étranglement est un multithread I/O de l'environnement. Vous devriez essayer de sérialiser vos I/O lorsque cela est possible.
Merci Mike, juste pour confirmer, est-ce s'appliquent uniquement lors de la lecture d'un fichier unique, ou s'appliquent également lors de la lecture de plusieurs fichiers (thread 1 lire fichier1 ,thread2 lire fichier2)
Ce que j'ai dit s'applique à TOUTES les e/S de disque sur un disque unique, indépendamment de savoir si il y a des fichiers séparés. Bien sûr, la mise en cache par le système d'exploitation ou le disque aura un certain effet sur les résultats réels.
Mais il y a des systèmes de fichiers qui vous permet de distribuer des fichiers sur différentes disque/disque sections de façon linéaire à l'échelle de votre I/O.
OriginalL'auteur Mike
De files d'attente multiples lectures et les écritures ne va pas aider lorsque vous êtes en cours d'exécution à l'encontre d'un disque. Si votre application a également réalisé un gros travail au niveau du PROCESSEUR, alors vous pourriez faire votre lit et écrit de manière asynchrone et de laisser le CPU à travailler alors que le disque I/O se produit en arrière-plan. Alternativement, obtenir un deuxième disque dur physique: lecture à partir d'un, écrire pour les autres. Pour la taille modeste des ensembles de données qui est souvent efficace et un peu moins cher que d'écrire du code.
Dbger, il dépend de la nature de vos données. Si vous êtes en mesure de file un deuxième asynchrones extraction d'être satisfait lors du traitement de la première extraction de données que vous êtes en affaires. Encore une fois, c'est plus efficace si le disque n'est pas occupé avec d'autres I/O, donc peut-être pas applicable à votre situation immédiate.
OriginalL'auteur Curt Nichols
Ce n'est pas vraiment une réponse à votre question, mais plutôt une re-conception (nous détestons tous, mais ne peut pas s'empêcher de faire). Comme déjà mentionné, en essayant d'accélérer les I/O sur un disque dur avec plusieurs threads ne sera probablement pas aider.
Cependant, il pourrait être possible d'utiliser une autre approche selon les données sur la sensibilité, les besoins en termes de débit, la taille des données, etc. Il ne serait pas difficile de créer une structure dans la mémoire conserve une image des données et permet facilement/rapidement des mises à jour des lignes de texte n'importe où dans les données. Vous pouvez ensuite utiliser un thread dédié qui surveille simplement que la structure et dont le travail consiste à écrire les données sur le disque. L'écriture des données de manière séquentielle sur le disque peut être extrêmement rapide; il peut être beaucoup plus rapide que de chercher au hasard pour les différentes sections et l'écriture des morceaux.
1 seconde pour écrire 2 MO? Qui semble étonnamment lente. J'ai juste couru un test écrit 10M à un fichier dans environ 100ms, et mon PC est pas la vitesse réelle de la machine (3.2 GHz et I
Je suis en utilisant std::ofstream pour enregistrer beaucoup de données séparées dans une boucle. comme "for(...){streamOut << x; streamOut<<y}", et j'ai aussi un 7200 tr / min lecteur avec un dual core 2.16 GHz CPU
Voilà qui est intéressant. Si j'ai du temps, j'ai peut-être de tester ça sur mon PC de la curiosité. J'ai été tout simplement à l'aide de l'Api Win32 (CreateFile, WriteFile). Mais en réalité, j'attendrais la streamio de passer par les Api sur Win32. Ou si non, il serait encore à travers une sorte de tampon I/O. La latence moyenne d'un 7200 tr / min disque doit être de moins de 5ms. Qui devraient permettre un lot de tampon écrit. Je suppose que si le disque a été complètement fragmenté en 4096 blocs, il serait arrivé à 1 seconde/MO.
MarkW, il s'avère que la plupart du temps est passé sur la chaîne de formatage lors de l'appel de "streamOut << x << ""<< y << ""<< z <<endl". J'ai ensuite changé le code pour le format de toutes ces données dans une chaîne de caractères en premier, et puis écrire sur le fichier en une fois, il en coûte environ 24ms à écrire 2M de données. Puis par la parallélisation de la chaîne de formatage il y a un gain de performance notable. Merci beaucoup.
OriginalL'auteur Mark Wilkins