Je dois lire une matrice 8192x8192 en mémoire. Je veux le faire aussi vite que possible. dans la fonction sur un système à deux cœurs avec 2 threads, cela prend p> < PRE> XXX PRE> Y a-t-il un moyen d'optimiser cela plus loin? p> p>
À l'heure actuelle, j'ai cette structure: parallelLeLead code>, je pars chaque ligne, do
atoi code> et peupler la matrice. Le parallélisme est linéaire comme thre thread t parses ligne
t, t + 1 * num_threads .. code> p>
4 Réponses :
Une chose qui vaut la peine d'être envisagée est d'allouer deux petits tampons d'entrée (disons qu'ils seront 200 lignes chacun). p>
a ensuite un thread de lecture de données dans les tampons d'entrée. Lorsqu'un tampon d'entrée est plein, passez-le à un deuxième fil qui fait l'analyse. Ce deuxième thread pourrait utiliser un pool de threads pour une analyse simultanée (cocher OpenMP). p>
Vous devrez utiliser des verrous / mutexs pour vous assurer que l'un ou l'autre fil a un accès exclusif. P>
Ce serait mieux parce que l'analyse est désormais simultanée avec la lecture du fichier, et votre accès à la mémoire au tampon est plus local et s'intégrera à votre cache de la CPU. Cela peut améliorer la lecture et l'analyse de la vitesse. p>
Si Fgets est le goulot d'étranglement, vous pouvez également lire le fichier en mémoire comme binaire. Cela pourrait améliorer la vitesse de lecture, mais vous obligera à faire une analyse supplémentaire et rendra l'optimisation susmentionnée plus difficile à effectuer. p>
Essayez un fil parent qui charge la matrice de caractères en utilisant quelque chose comme Fread pour tout charger dans 1 io comme une grande grande chaîne. P>
Demandez aux parents la chaîne et trouvez 1 ligne, ou calculez où la première ligne est basée sur des tailles. Remettre le traitement de cette ligne sur un fil. Ligne suivante, rincer, répéter, jusqu'à ce que eof. Synchroniser avec les fils. Fait. P>
Les meilleures performances que vous pouvez obtenir avec le fichier E / S via la mappage de mémoire. C'est un exemple . Je démarrerais à partir d'une seule conception filetée et si le traitement post-charge s'avère être un goulot d'étranglement le rendre parallèle. P>
C'est une mauvaise idée de le faire de cette façon. Les threads peuvent obtenir vos cycles de plus de CPU si vous avez suffisamment de nœuds, mais vous n'avez toujours qu'un seul disque dur. Les threads si inévitablement ne peuvent pas améliorer la vitesse de lecture des données de fichier. P>
Ils rendent effectivement beaucoup pire. La lecture des données d'un fichier est la plus rapide lorsque vous accédez au fichier séquentiellement. Cela minimise le nombre de recherches de la tête de lecteur, de loin l'opération la plus coûteuse sur un lecteur de disque. En divisant la lecture sur plusieurs threads, chacun en lisant une partie différente du fichier, vous faites que la tête du lecteur saute constamment d'avant en arrière. Très, très mauvais pour le débit. P>
Utilisez uniquement un thread em> pour lire les données de fichier. Vous pourriez être capable de le chevaucher avec certains cycles de calcul sur les données de fichier en démarrant un thread une fois qu'un morceau des données de fichier est chargé. p>
faites em> attention à l'effet de test. Lorsque vous réécrivez votre programme, généralement après avoir modifié votre code quelque peu, il est probable que le programme puisse retrouver des données de fichier dans le cache du système de fichiers afin qu'il ne soit pas à lire dans le disque. C'est une vitesse de bus de mémoire très rapide, une copie mémoire à mémoire. Passablement probablement sur votre jeu de données car il n'est pas très grand et convient facilement à la quantité de RAM Une machine moderne. Cela ne se produit pas (typiquement) sur une machine de production. Assurez-vous donc de dégager le cache pour obtenir des nombres réalistes, tout ce qu'il faut sur votre système d'exploitation. P>
Il est pas i> lire le fichier en parallèle, il convertit la chaîne en int8_t en parallèle de la mémoire. Il n'y a rien de mal avec ça.
Je n'ai jamais réclamé qu'il y avait quelque chose de mal avec ça. Je me suis recommandé de se chevaucher avec le fil qui lit les données.
Peut-être que vous pourriez commencer les threads de population en parallèle avec les E / S, car suffisamment de données deviennent disponibles.
Pour être honnête, je suis un peu surpris que vous ayez réussi à obtenir une amélioration de la performance i> de la lecture du même fichier à partir de plusieurs threads ... Lors de la référence, assurez-vous que le fichier est en réalité lue de le disque, et pas du cache?
@aix I HAV a utilisé 2 threads juste par exemple. J'ai la parallylisation de la partie de prétraitement, ceci est après que les données sont lues dans la mémoire.
Le mieux que vous pouvez éventuellement obtenir est moins de deux fois plus rapide, même si vous pouvez rendre le prétraitement
code> prendre 0 heure. Est-ce que ça vaut le coup? (Voir la loi d'Amdahl.)
@ALANSTOKES Je ne vois aucun préjudice à économiser 4,44 secondes si j'ai les ressources. En fait, j'ai pu réduire le temps de prétraitement à 0,1 sur une machine avec 40 cœurs.
@vanza Vous avez peut-être raison, c'était quelque chose que je pensais aussi. Je pourrais laisser des fgets () continuer dans un fil et démarrer la tâche de prétraitement dans un autre fil, mais cela nécessitera que mes fils attendent si les données ne sont pas disponibles, et j'ai vu des pénalités de performance avec cela.
Les seules façons que je connaisse pour améliorer les performances de lecture du disque sont les suivantes: 1) Lisez les données d'une source compressée. 2) Utilisez des disques plus rapides ou une matrice RAID. ou 3) diviser les données sur des disques distincts et lire 1 thread par disque. Habituellement, si un seul thread ne peut pas suivre votre disque de lecture, vous avez de gros problèmes.
Stockez vos données en binaires. Si chaque élément matriciel peut prendre au plus 256 valeurs différentes, nous examinons 64 Mo ici, ce qui devrait être facilement traitée par le matériel moderne. Vous pouvez ensuite créer une mémoire de mémoire le fichier directement dans votre programme.
@Kerreksb Vous voulez dire que le fichier d'entrée que je lis devrait être binaire? Je ne peux pas modifier le format du fichier d'entrée.
@ SUD03R: Vous pouvez rédiger un outil de conversion, si cela améliorerait votre efficacité opérationnelle globale.