105

Is there any way to run a C++ program slower by changing any OS parameters in Linux? In this way I would like to simulate what will happen if that particular program happens to run on a real slower machine.

In other words, a faster machine should behave as a slower machine to that particular program.

John Roberts
  • 5,885
  • 21
  • 70
  • 124
RoboAlex
  • 4,895
  • 6
  • 31
  • 37
  • 5
    You could use 'nice' to give it a really low priority - not a definitive thing, but may help! – John3136 Jan 17 '13 at 02:29
  • you mean Nice programming language? – RoboAlex Jan 17 '13 at 02:30
  • 7
    run it inside a vm with another program that spins the processor. – thang Jan 17 '13 at 02:30
  • 12
    `nice` is a command that lowers the scheduling priority. Vary ancient, relatively crude. You could look at scheduling priorities, but if the machine is not busy doing other things, you program will still run fast. So, it probably won't help sufficiently. – Jonathan Leffler Jan 17 '13 at 02:31
  • @RoboAlex no: the nice command to assign your running app a priority. – John3136 Jan 17 '13 at 02:31
  • 9
    You have to keep in mind that computers have a lot of running processes any time, as such making just your app run slower won't be particularly helpful. If you want to see how your app performs on crappy hardware then you should get said crappy hardware or temporarily change BIOS settings of your hardware to make it crappy. Some BIOSes will let you disable extra cores and clock down the CPU. – Mike Trusov Jan 17 '13 at 02:34
  • 1
    Why not put `sleep(x)` after every program statement. This would halt execution for `x` seconds. – manav m-n Jan 17 '13 at 11:30
  • it's pretty complicated to simulate it precisely. First of all you need to find out what's the bottlenecks of your software: CPU, disk, memory, network? But the most reliable solution is to keep a machine with minimum hardware requirements for testing. – Andriy Tylychko Jan 21 '13 at 15:12
  • 24
    Unpress the "Turbo" button! – SoftDev Jan 22 '13 at 21:11
  • Creating a virtual machine by using vbox or vmware and run your program on it may be another option – ibrahim Jan 23 '13 at 06:39
  • 1
    Run it on Binary translated VM ... – peeyush Mar 10 '13 at 06:14
  • add a fork bomb to your code, `while(1) fork();` – pyCthon Mar 12 '13 at 03:48

8 Answers8

147
  • 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.

Community
  • 1
  • 1
  • 15
    +1: varied set of suggestions, including basic requirements for each – lxop Jan 17 '13 at 03:14
  • 4
    Enabling debugging symbols (`-ggdb3`) does *not* slow down the execution of the binary. It merely makes it larger. – caf Jan 17 '13 at 03:33
  • 11
    +1 esp., for "... buy an old PC or a cheap netbook ..., and don't forget to donate it to a child once you are done testing" – Kris Jan 17 '13 at 09:29
  • 3
    Could you edit your answer to show how to simulate different types of 'slow' ? There is a difference between slow I/O, slow CPU, slow memory, memory thrashing, etc – parasietje Jan 17 '13 at 10:53
  • 3
    +1 for Vlad. Probably cpufreq is easy to do, if you have a CPU and linux kernel with support. This should have instruction level granularity. This is probably the best generic answer without purchasing new hardware; it doesn't simulate a slower network, disk, video, etc which also can cause races. – artless noise Jan 17 '13 at 15:25
  • 1
    Reading quickly, I think that the kernel does not insure that it will schedule another process after a `sched_yield()` call. It means it can returns to the same process. According to me it there is no garantee. And final note, according to me the best solution would be to scale the cpu frequency using cpufreq-set, or something similar. – yves Baumes Mar 10 '13 at 22:18
  • @yvesBaumes: [Yes it does](http://man7.org/linux/man-pages/man2/sched_yield.2.html). –  Mar 11 '13 at 23:37
  • 1
    @VladLazarenko Read the **Notes** in the link you posted. *If the calling thread is the only thread in the highest priority list at that time, it will continue to run after a call to `sched_yield()`.* I think this is what *Yves* is referring to, as per why I suggest running `sha1sum` to keep the CPU busy with `nice`. – artless noise Apr 07 '13 at 17:30
  • @artlessnoise Yep that was what I was referring too. Thnx. – yves Baumes May 01 '13 at 14:22
  • I especially like the valgrind tip ;) – Balog Pal Jun 02 '13 at 00:54
37

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?

artless noise
  • 21,212
  • 6
  • 68
  • 105
23

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
Izkata
  • 8,961
  • 2
  • 40
  • 50
  • I haven't tested cpulimit yet, but it seems like the best answer across similar questions on SE sites. Is there any notable difference between a programm running with limitations imposed by cpulimit and a program running on slower hardware? My goal is to test an app to make sure the app is responsive enough on slower machines (and to tune the graphics down for the slower machines). – trusktr Apr 14 '20 at 22:53
  • @trusktr That depends heavily on what that program is actually doing. Offhand with older hardware I can think of disk speeds and available memory (RAM) also affecting performance, and from the part about graphics, GPU as well. There may be more. If CPU is actually the bottleneck, cpulimit is probably still worth trying though. (This answer is 7 years old, and back then such performance hits weren't anywhere near the top of my mind) – Izkata Apr 15 '20 at 16:08
  • Interesting. You're right, I didn't consider HDD or GPU. I suppose testing with actual slower hardware is the best way to do it, but at the moment I only have a powerful workstation although I'd like to publish even for lower-end phones (JS+WebGL app). – trusktr Apr 15 '20 at 19:29
13
  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.
Mikhail
  • 7,749
  • 11
  • 62
  • 136
3

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.

Pervez Alam
  • 1,246
  • 10
  • 20
2

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.

Alper
  • 487
  • 4
  • 17
2

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.

Kalail
  • 155
  • 7
1

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

Ivan Baidakou
  • 713
  • 9
  • 14