Question

Je suis en train de tirer le maximum des performances d'un pilote de bloc Linux pour un périphérique de stockage haut de gamme. Un problème qui m'a un peu déconcerté en ce moment est la suivante: si une tâche utilisateur démarre une opération d'E / S (lecture ou écriture) sur une unité centrale de traitement et l'interruption de l'appareil se produit sur un autre CPU, j'encoure environ 80 microsecondes de retard avant la tâche reprend l'exécution.

Je peux voir cela en utilisant O_DIRECT contre le dispositif de bloc brut, donc ce n'est pas cache de page ou filesystem- liés. Le pilote utilise make_request pour recevoir des opérations, de sorte qu'il n'a pas de file d'attente et ne demande pas d'utiliser le programmateur noyau E / S (vous devez me faire confiance, il est beaucoup plus rapide de cette façon).

Je peux démontrer à moi-même que le problème se produit entre l'appel bio_endio sur une CPU et la tâche reprogrammée sur un autre CPU. Si la tâche est sur la même CPU, il commence très rapidement, et si la tâche est sur un autre CPU physique, il faut beaucoup plus - habituellement environ 80 microsecondes plus sur le système de test actuel (x86_64 sur le chipset Intel 5520 [NUMA] ).

Je peux instantanément doubler mes performances en définissant le processus et l'affinité cpu IRQ à la même CPU physique, mais ce n'est pas un bon à long terme solution-- Je préférerais être en mesure d'obtenir de bonnes performances, peu importe où I / Os proviennent. Et je n'ai qu'une seule IRQ donc je ne peux le conduire à une unité centrale de traitement à la fois -. Rien si plusieurs threads sont en cours d'exécution sur plusieurs processeurs

Je peux voir ce problème sur les noyaux de Centos 5.4 de 2.6.18 à 2.6.32 ligne principale.

La question est: pourquoi faut-il plus pour le processus utilisateur de reprendre, si j'ai appelé bio_endio d'un autre CPU? Est-ce un problème de planificateur? Et est-il possible d'éliminer ou de réduire le délai?

Était-ce utile?

La solution 4

On dirait que j'ai mal compris le problème un peu: il semble être lié à misses cache; lorsque les interruptions de manipulation cpu n'a pas été le cpu qui a commencé le i / o, le cpu peut frapper une utilisation à 100%, puis tout ralentit, donnant l'impression qu'il ya un long délai de communication entre CPUs.

Merci à tous pour leurs idées.

Autres conseils

Si vous avez terminé votre E / S sur un processeur particulier, alors que le processeur est immédiatement libre de commencer à travailler sur un nouveau thread - si vous avez terminé votre i / o sur le même processeur que le fil l'a demandé, puis la prochaine fil est susceptible d'être celui que vous avez terminé i / o pour.

Par contre, si vous avez terminé sur un processeur différent, le fil qui a demandé au i / o ne pas à courir immédiatement - il doit attendre jusqu'à ce que tout ce qui est en cours d'exécution termine son quantum ou quitte son poste sinon la CPU <. / p>

Pour autant que je comprends.

Il pourrait être juste le temps de latence inhérent à l'émission d'une IIP de la CPU qui a terminé le bio à l'unité centrale de traitement où la tâche se devrait - pour tester cela, essayez de démarrer avec idle=poll

.

Ce patch vient d'être affecté à LKML, la mise en œuvre QUEUE_FLAG_SAME_CPU dans la couche de dispositif de blocage, qui est décrite comme suit:

  

Ajouter un drapeau pour faire une demande complète sur   cpu où la demande est soumise. le   drapeau implique QUEUE_FLAG_SAME_COMP. Par   par défaut, il est désactivé.

On dirait que ce pourrait être juste ce dont vous avez besoin ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top