Faire tourner un programme lentement

102

Existe-t-il un moyen d'exécuter un programme C ++ plus lentement en modifiant les paramètres du système d'exploitation sous Linux? De cette façon, je voudrais simuler ce qui se passera si ce programme particulier s'exécute sur une machine vraiment plus lente.

En d'autres termes, une machine plus rapide devrait se comporter comme une machine plus lente pour ce programme particulier.

RoboAlex
la source
5
Vous pouvez utiliser «gentil» pour lui donner une priorité très basse - ce n'est pas une chose définitive, mais cela peut aider!
John3136
7
exécutez-le dans une machine virtuelle avec un autre programme qui fait tourner le processeur.
thang
12
niceest une commande qui abaisse la priorité de planification. Varie ancienne, relativement brute. Vous pouvez examiner les priorités de planification, mais si la machine n'est pas occupée à faire autre chose, votre programme fonctionnera toujours rapidement. Donc, cela n'aidera probablement pas suffisamment.
Jonathan Leffler
9
Vous devez garder à l'esprit que les ordinateurs ont de nombreux processus en cours d'exécution à tout moment, par conséquent, il ne sera pas particulièrement utile de ralentir l'exécution de votre application. Si vous voulez voir comment votre application fonctionne sur un matériel de merde, vous devriez vous procurer ce matériel de merde ou modifier temporairement les paramètres du BIOS de votre matériel pour le rendre merdique. Certains BIOS vous permettront de désactiver les cœurs supplémentaires et de ralentir le processeur.
Mike Trusov
23
Décompressez le bouton "Turbo"!
SoftDev

Réponses:

145
  • Réduisez la priorité à l'aide de nice(et / ou renice). Vous pouvez également le faire par programme à l'aide d' nice()un appel système. Cela ne ralentira pas la vitesse d'exécution en soi, mais obligera le programmateur Linux à allouer moins (et peut-être plus court) les délais d'exécution, à préempter plus souvent, etc. Voir Planification des processus (chapitre 10) de Comprendre le noyau Linux pour plus de détails sur la programmation .
  • Vous voudrez peut-être augmenter la fréquence d'interruption de la minuterie pour mettre plus de charge sur le noyau, ce qui ralentira à son tour tout. Cela nécessite une reconstruction du noyau.
  • Vous pouvez utiliser le mécanisme de mise à l'échelle de la fréquence du processeur (nécessite un module de noyau) et contrôler (ralentir, accélérer) le processeur à l'aide ducpufreq-set commande.
  • Une autre possibilité est d'appeler sched_yield() , ce qui donnera un quantum à d'autres processus, dans les parties critiques de performance de votre programme (nécessite un changement de code).
  • Vous pouvez brancher des fonctions communes comme malloc(), free(), clock_gettime()etc. , en utilisant LD_PRELOAD , et faire des choses stupides comme brûler quelques millions de cycles CPU avec rep; hop;, insérer des barrières de mémoire , etc. Cela va ralentir le programme sûr. (Voir cette réponse pour un exemple de la façon de faire certaines de ces choses).
  • Comme @Bill l'a mentionné, vous pouvez toujours exécuter Linux dans un logiciel de virtualisation qui vous permet de limiter la quantité de ressources CPU, de mémoire, etc. allouées.
  • Si vous voulez vraiment que votre programme soit lent, exécutez-le sous Valgrind (peut également vous aider à trouver des problèmes dans votre application comme des fuites de mémoire, de mauvaises références de mémoire, etc.).
  • Une certaine lenteur peut être obtenue en recompilant votre binaire avec des optimisations désactivées (ie -O0et activer les assertions (ie -DDEBUG).
  • Vous pouvez toujours acheter un vieux PC ou un netbook bon marché (comme un ordinateur portable par enfant , et n'oubliez pas de le donner à un enfant une fois que vous avez terminé les tests) avec un processeur lent et exécutez votre programme.

J'espère que ça aide.

Communauté
la source
15
+1: ensemble varié de suggestions, y compris les exigences de base pour chacune
lxop
4
Activation des symboles de débogage ( -ggdb3) ne pas ralentir l'exécution du binaire. Cela ne fait que l'agrandir.
caf
11
+1 esp., Pour "... achetez un vieux PC ou un netbook bon marché ..., et n'oubliez pas de le donner à un enfant une fois que vous avez terminé le test"
Kris
3
Pourriez-vous modifier votre réponse pour montrer comment simuler différents types de «lent»? Il y a une différence entre les E / S lentes, le processeur lent, la mémoire lente, la mémoire vive, etc.
Parasietje
3
+1 pour Vlad. Cpufreq est probablement facile à faire, si vous avez un processeur et un noyau Linux avec support. Cela devrait avoir une granularité de niveau d'instruction. C'est probablement la meilleure réponse générique sans acheter de nouveau matériel; il ne simule pas un réseau, un disque, une vidéo, etc. plus lent, ce qui peut également provoquer des courses.
bruit naïf
36

QEMU est un émulateur de processeur pour Linux. Debian a des paquets pour cela (j'imagine que la plupart des distributions le seront). Vous pouvez exécuter un programme dans un émulateur et la plupart d'entre eux devraient prendre en charge le ralentissement des choses. Par exemple, Miroslav Novak a des correctifs pour ralentir QEMU.

Alternativement, vous pouvez croiser la compilation vers un autre CPU-linux (arm-none-gnueabi-linux, etc.) puis demander à QEMU de traduire ce code pour qu'il s'exécute.

La bonne suggestion est simple et peut fonctionner si vous la combinez avec un autre processus qui consommera du processeur.

nice -19 test &
while [ 1 ] ; do sha1sum /boot/vmlinuz*; done;

Vous n'avez pas dit si vous aviez besoin de graphiques, de fichiers et / ou d'E / S réseau? Savez-vous quelque chose sur la classe d'erreur que vous recherchez? Est-ce une condition de concurrence, ou le code fonctionne-t-il simplement mal sur le site d'un client?

Edit: Vous pouvez également utiliser des signaux comme STOP et CONT pour démarrer et arrêter votre programme. Un débogueur peut également le faire. Le problème est que le code s'exécute à pleine vitesse , puis s'arrête. La plupart des solutions avec le planificateur Linux auront ce problème. Il y avait une sorte d'analyseur de thread d'Intel Afair. Je vois les notes de publication de Vtune . C'est Vtune, mais j'étais à peu près sûr qu'il existe un autre outil pour analyser les courses de threads. Voir: Intel Thread Checker , qui peut vérifier certaines conditions de course de threads. Mais nous ne savons pas si l'application est multithread?

bruit naïf
la source
1
et bochs est un émulateur cpu plus ancien et plus lent (uniquement x86).
osgx
22

Utilisez cpulimit:

Cpulimit est un outil qui limite l'utilisation du CPU d'un processus (exprimé en pourcentage, pas en temps CPU). Il est utile de contrôler les travaux par lots, lorsque vous ne voulez pas qu'ils consomment trop de cycles CPU. Le but est d'empêcher un processus de s'exécuter pendant plus d'un délai spécifié. Cela ne change pas la valeur de Nice ou d'autres paramètres de priorité de planification, mais l'utilisation réelle du processeur . En outre, il est capable de s'adapter à la charge globale du système , de manière dynamique et rapide.

Le contrôle de la quantité de cpu utilisée se fait en envoyant des signaux SIGSTOP et SIGCONT POSIX aux processus.

Tous les processus enfants et threads du processus spécifié partageront le même pourcentage de CPU.

C'est dans les dépôts Ubuntu. Juste

apt-get install cpulimit

Voici quelques exemples sur la façon de l'utiliser sur un programme déjà en cours d'exécution:

Limitez le processus 'bigloop' par nom d'exécutable à 40% du processeur:

cpulimit --exe bigloop --limit 40
cpulimit --exe /usr/local/bin/bigloop --limit 40 

Limiter un processus par PID à 55% CPU:

cpulimit --pid 2960 --limit 55
Izkata
la source
Je n'ai pas encore testé cpulimit, mais cela semble être la meilleure réponse à des questions similaires sur des sites SE. Existe-t-il une différence notable entre un programme exécuté avec des limitations imposées par cpulimit et un programme exécuté sur un matériel plus lent? Mon objectif est de tester une application pour m'assurer que l'application est suffisamment réactive sur les machines plus lentes (et pour ajuster les graphiques pour les machines plus lentes).
trusktr le
@trusktr Cela dépend fortement de ce que fait réellement ce programme. Avec un matériel plus ancien, je peux penser aux vitesses de disque et à la mémoire disponible (RAM) qui affectent également les performances, ainsi que de la partie sur les graphiques, le GPU. Il peut y en avoir plus. Si le CPU est réellement le goulot d'étranglement, cpulimit vaut probablement la peine d'être essayé. (Cette réponse a 7 ans, et à l'époque, de telles performances n'étaient pas du tout dans mon esprit)
Izkata
Intéressant. Vous avez raison, je n'ai pas considéré le disque dur ou le GPU. Je suppose que tester avec du matériel réel plus lent est la meilleure façon de le faire, mais pour le moment, je n'ai qu'un poste de travail puissant, même si j'aimerais publier même pour les téléphones bas de gamme (application JS + WebGL).
trusktr
13
  1. Obtenez un vieil ordinateur
  2. Les packages d'hébergement VPS ont tendance à fonctionner lentement, ont beaucoup d'interruptions et des latences extrêmement variables. Le moins cher vous allez, le pire sera le matériel. Contrairement au matériel vraiment ancien, il y a de fortes chances qu'il contienne des jeux d'instructions (SSE4) qui ne se trouvent généralement pas sur l'ancien matériel. Néanmoins, si vous voulez un système qui marche lentement et qui se ferme souvent, un hôte VPS bon marché sera le démarrage le plus rapide.
Mikhail
la source
3

Si vous souhaitez simplement simuler votre programme pour analyser son comportement sur une machine très lente, vous pouvez essayer de faire exécuter votre programme entier comme un threadautre programme principal. .

De cette manière, vous pouvez prioriser le même code avec des priorités différentes dans quelques threads à la fois et collecter les données de votre analyse. Je l'ai utilisé dans le développement de jeux pour l'analyse du traitement des images.

Pervez Alam
la source
2

Utilisez veille ou attendez à l'intérieur de votre code. Ce n'est pas la manière la plus brillante de faire mais acceptable sur tous les types d'ordinateurs avec des vitesses différentes.

Alper
la source
2

La façon la plus simple de le faire serait d'envelopper votre code exécutable principal dans une boucle while avec un sommeil à la fin.

Par exemple:

void main()
{
    while 1
    {
        // Logic
        // ...
        usleep(microseconds_to_sleep)
    }
}

Comme les gens le mentionneront, ce n'est pas le moyen le plus précis, car votre code logique fonctionnera toujours à vitesse normale mais avec des retards entre les exécutions. En outre, cela suppose que votre code logique est quelque chose qui s'exécute dans une boucle.

Mais c'est à la fois simple et configurable.

Kalail
la source