让程序慢慢运行

有没有办法通过改变 Linux 中的操作系统参数来减慢 C + + 程序的运行速度?通过这种方式,我想模拟一下,如果这个特定的程序恰好在一台真正的速度较慢的机器上运行,会发生什么情况。

换句话说,对于这个特定的程序,一台速度更快的机器应该表现得像一台速度更慢的机器。

15664 次浏览

QEMU is a CPU emulator for Linux. Debian has packages for it (I imagine most distros will). You can run a program in an emulator and most of them should support slowing things down. For instance, Miroslav Novak has patches to slow down QEMU.

Alternatively, you could cross compile to another CPU-linux (arm-none-gnueabi-linux, etc) and then have QEMU translate that code to run.

The nice suggestion is simple and may work if you combine it with another process which will consume cpu.

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

You did not say if you need graphics, file and/or network I/O? Do you know something about the class of error you are looking for? Is it a race condition, or does the code just perform poorly at a customer site?

Edit: You can also use signals like STOP and CONT to start and stop your program. A debugger can also do this. The issue is that the code runs a full speed and then gets stopped. Most solutions with the Linux scheduler will have this issue. There was some sort of thread analyzer from Intel afair. I see Vtune Release Notes. This is Vtune, but I was pretty sure there is another tool to analyze thread races. See: Intel Thread Checker, which can check for some thread race conditions. But we don't know if the app is multi-threaded?

  • Lower the priority using nice (and/or renice). You can also do it programmatically using nice() system call. This will not slow down the execution speed per se, but will make Linux scheduler allocate less (and possibly shorter) execution time frames, preempt more often, etc. See Process Scheduling (Chapter 10) of Understanding the Linux Kernel for more details on scheduling.
  • You may want to increase the timer interrupt frequency to put more load on the kernel, which will in turn slow everything down. This requires a kernel rebuild.
  • You can use CPU Frequency Scaling mechanism (requires kernel module) and control (slow down, speed up) the CPU using the cpufreq-set command.
  • Another possibility is to call sched_yield(), which will yield quantum to other processes, in performance critical parts of your program (requires code change).
  • You can hook common functions like malloc(), free(), clock_gettime() etc. using LD_PRELOAD, and do some silly stuff like burn a few million CPU cycles with rep; hop;, insert memory barriers etc. This will slow down the program for sure. (See this answer for an example of how to do some of this stuff).
  • As @Bill mentioned, you can always run Linux in a virtualization software which allows you to limit the amount of allocated CPU resources, memory, etc.
  • If you really want your program to be slow, run it under Valgrind (may also help you find some problems in your application like memory leaks, bad memory references, etc).
  • Some slowness can be achieved by recompiling your binary with disabled optimizations (i.e. -O0 and enable assertions (i.e. -DDEBUG).
  • You can always buy an old PC or a cheap netbook (like One Laptop Per Child, and don't forget to donate it to a child once you are done testing) with a slow CPU and run your program.

Hope it helps.

  1. Get an old computer
  2. VPS hosting packages tend to run slowly, have lots of interruptions, and wildly varying latencies. The cheaper you go the worse the hardware will be. Unlike truly old hardware, there is a good chance they will contain instruction sets (SSE4) that are not usually found on old hardware. Neverthless, if you want a system that walks slowly and shutters often, a cheap VPS host will be the quickest start.

Use sleep or wait inside of your code. Its not the brightest way to do but acceptable in all kind of computer with different speeds.

Use cpulimit:

Cpulimit is a tool which limits the CPU usage of a process (expressed in percentage, not in CPU time). It is useful to control batch jobs, when you don't want them to eat too many CPU cycles. The goal is prevent a process from running for more than a specified time ratio. It does not change the nice value or other scheduling priority settings, but the real CPU usage. Also, it is able to adapt itself to the overall system load, dynamically and quickly.

The control of the used cpu amount is done sending SIGSTOP and SIGCONT POSIX signals to processes.

All the children processes and threads of the specified process will share the same percent of CPU.

It's in the Ubuntu repos. Just

apt-get install cpulimit

Here're some examples on how to use it on an already-running program:

Limit the process 'bigloop' by executable name to 40% CPU:

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

Limit a process by PID to 55% CPU:

cpulimit --pid 2960 --limit 55

If you just want to simulate your program to analyze its behavior on really slow machine, you can try making your whole program to run as a thread of some other main program.

In this manner you can prioritize same code with different priorities in few threads at once and collect data of your analysis. I have used this in game development for frame-processing analysis.

The simplest possible way to do it would be to wrap your main runable code in a while loop with a sleep at the end of it.

For example:

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

As people will mention, this isn't the most accurate way, since your logic code will still run at normal speed but with delays between runs. Also, it assumes that your logic code is something that runs in a loop.

But it is both simple and configurable.

You can increase load on CPUs via launching tools like stress or stress-ng