Comment pouvez-vous assurer que votre code s'exécute sans aucune variabilité dans le temps d'exécution en raison du cache?

StackOverflow https://stackoverflow.com/questions/69049

Question

Dans une application intégrée (écrite en C, sur un processeur 32 bits) avec des contraintes temps réel dures, le temps d'exécution du code critique (en particulier les interruptions) doit être constant.

Comment vous assurez-vous que la variabilité temporelle n'est pas introduite dans l'exécution du code, en raison notamment des caches du processeur (que ce soit L1, L2 ou L3)?

Notez que le comportement du cache nous préoccupe en raison de son effet énorme sur la vitesse d'exécution (parfois plus de 100: 1 par rapport à l'accès à la RAM). La variabilité introduite en raison de l’architecture de processeur spécifique est loin de l’ampleur du cache.

Était-ce utile?

La solution

Si vous pouvez mettre la main sur le matériel ou travailler avec quelqu'un qui le peut, vous pouvez désactiver le cache. Certains processeurs ont une broche qui, si elle est câblée à la terre au lieu de l’alimentation (ou peut-être dans l’autre sens), désactivera tous les caches internes. Cela donnera de la prévisibilité mais pas de la vitesse!

À défaut, le code du logiciel pourrait peut-être être écrit à certains endroits dans le but de remplir délibérément le cache de malbouffe. Si vous le faites bien, cela peut donner de la prévisibilité, et peut-être ne serait-il possible que dans certains endroits, donc la vitesse peut être meilleure que la désactivation totale des caches.

Enfin, si la vitesse importe vraiment - concevez avec soin le logiciel et les données comme si à l'ancienne programmation pour un ancien processeur 8 bits - gardez-le suffisamment petit pour qu'il puisse être contenu dans le cache L1. Je suis toujours étonné de constater à quel point les caches embarquées sont plus grandes que la RAM sur un mini-ordinateur (mumble-décennie). Mais ce sera un travail difficile et demande de l'intelligence. Bonne chance!

Autres conseils

Deux possibilités:

Désactivez entièrement le cache. L'application fonctionnera plus lentement, mais sans aucune variabilité.

Pré-chargez le code dans le cache et "verrouillez-le". La plupart des processeurs fournissent un mécanisme pour ce faire.

Il semble que vous vous référiez à une famille de processeurs x86 qui n'est pas conçue pour les systèmes temps réel. Il n'y a donc aucune garantie réelle d'exécution à temps constant (le processeur peut réorganiser les micro-instructions, car il existe une prédiction de branche et des instructions). file d'attente de pré-extraction qui est vidée chaque fois que le processeur prédit à tort des sauts conditionnels ...)

Cette réponse vous semblera sournoise, mais elle a pour but de vous faire penser:

  

N'exécutez le code qu'une seule fois.

La raison pour laquelle je dis cela est que beaucoup le rendra variable et que vous n’auriez peut-être même pas le contrôle dessus. Et quelle est votre définition du temps? Supposons que le système d'exploitation décide de placer votre processus dans la file d'attente.

Vous avez ensuite une imprévisibilité due aux performances du cache, à la latence de la mémoire, aux E / S du disque, etc. Tout cela se résume à une chose; parfois, il faut du temps pour obtenir les informations dans le processeur où votre code peut les utiliser. Y compris le temps nécessaire pour récupérer / décoder votre code lui-même.

En outre, quelle quantité de variance est acceptable pour vous? Il se peut que vous acceptiez 40 millisecondes ou 10 nanosecondes.

En fonction du domaine d'application, vous pouvez même simplement masquer ou masquer la variance. Les infographistes effectuent des rendus hors mémoire d’écran depuis des années pour masquer les écarts de rendu de chaque image.

Les solutions traditionnelles suppriment simplement le plus de choses à taux variable connues. Chargez des fichiers dans la RAM, chauffez le cache et évitez les E / S.

Si vous passez tous les appels de fonction dans le code critique 'inline' et réduisez le nombre de variables que vous possédez, vous pourrez ainsi leur attribuer le type 'register'. Cela devrait améliorer la durée d'exécution de votre programme. (Vous devez probablement le compiler de manière spéciale car les compilateurs ont tendance à ignorer vos balises 'register')

Je suppose que vous avez assez de mémoire pour ne pas causer de fautes de page lorsque vous essayez de charger quelque chose de la mémoire. Les fautes de page peuvent prendre beaucoup de temps.

Vous pouvez également consulter le code de l'assembly généré pour savoir s'il existe de nombreuses branches et instances de mémoire susceptibles de modifier votre code en cours d'exécution.

Si une interruption survient dans l'exécution de votre code, cela prendra plus de temps. Avez-vous des interruptions / exceptions activées?

Préallouez la mémoire et assurez-vous que les interruptions n'affectent pas le cache (impossible, à droite).

/ Allan

Comprenez votre temps d'exécution dans le pire des cas pour des opérations complexes et utilisez des minuteries.

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