13

I was wondering if there is a simple way to "turn on" all 100% of the CPU so that I can run processes faster (such as python calculations).

1) Is this possible?

2) Is there an easy way to revert back to normal?

3) Is there a way to use less CPU if desired?

I'm thinking of a command line interaction like:

pi@raspberry:~ $ sudo turnOnFourCores python run.py

10
  • 1
    The short answer is No Commented Nov 21, 2017 at 23:35
  • 17
    The long answer is "If it were that simple, it would be the default"
    – Shadow
    Commented Nov 22, 2017 at 0:35
  • 18
    Both of your comments are misleading and could imply that the Pi has 4 cores but only ever uses 1. A better answer is that all four cores ARE already on, but that Python (and any other program, for that matter) will only use more than 1 core unless they're multi-threaded. Python can still effectively be stuck using a single core even with multi-threading due to the global interpreter lock, but that's a bit beyond the scope of this question. Commented Nov 22, 2017 at 1:02
  • 13
    To clarify, I think the OP has a misunderstanding how multi-core CPUs work, and your answers only reinforce their misunderstanding. Commented Nov 22, 2017 at 1:08
  • 7
    The easiest way to make a Python program faster is to re-write in a compiled language (or at least make the time critical tasks use a c module).
    – Milliways
    Commented Nov 22, 2017 at 3:09

12 Answers 12

23

By default, any computer will try to use all of its cores when it can. However, it can only achieve this when an application is multi-threaded. If it is not (i.e. a Python script that doesn't use the threading module), then it can only use at maximum, one core. This equates to 25% of the CPU on a four-core CPU. If you'd like to modify your script to use multiple cores, you can split your calculation into multiple parts, and multi-thread it as shown in the Python documentation.

Update:

As Anon answered, this will fail to work without working with Python's GIL (Global Interpreter Lock). This allows tasks to operate (seemingly) at the same time, but does not allow code to run across multiple cores. If you are using modules written in C (e.g. numpy), they can allow you to use multiple cores go around that limitation. Additionally, if that is not an option, Python offers multiprocessing, which allows you to run any task on multiple cores.

4
  • The update - which is correct - explains why the first part of the answer is wrong with respect to Python. You only get around this limitation of Python by writing modules C or some compiled language, at which point you're not really writing Python at all anymore. If performance is critical, going to a compiled language is the right answer. (Multiprocessing is not the same from a resource usage perspective.)
    – Brick
    Commented Nov 22, 2017 at 4:46
  • 5
    @Brick Just to be clear, a compiled language is certainly not a requirement for proper in-process multithreading. Heck, even Python's GIL is an implementation detail (granted, for the popular CPython) - there are other Python interpreters that will happily multithread, e.g. Jython and IronPython.
    – Bob
    Commented Nov 22, 2017 at 7:10
  • 5
    Adding to the confusion, Python is compiled; in the case of CPython it compiles to the CPython bytecode which is run in the CPython VM. For Jython, it's compiled to Java bytecode which is run in the JVM. And finally, IronPython compiles to CIL, which targets the .NET runtime. So, "going to a compiled language" for performance doesn't really make sense ;)
    – marcelm
    Commented Nov 22, 2017 at 15:46
  • 1
    any computer will try to use all of its cores when it can. Not really, it will only use all of its cores (or do anything else) when it is told to. That distinction may seem obvious or even patronising to the experienced, but it sounds like the OP needs to appreciate that it doesn't happen automatically.
    – nekomatic
    Commented Nov 23, 2017 at 14:23
14

I was wondering if there is a simple way to "turn on" all 100% of the CPU so that I can run processes faster (such as python calculations).

Not in the sense that I think you are implying. This is not an issue specific to the pi, either, it is a logical constraint.

All by themselves computers currently do not have much capacity to determine that a process running as a single thread can instead be run in parallel. Note that at the point when they might have this capacity, there would be no need for computer programmers, because a computer system that could do this might as well write its own code1..

Consider the following simple math expression:

(4 + 2) * 17 / (3 + 6)

There is some potential for this to be calculated in parallel, but it is logically limited. I'd say there's no point in more than two threads, and even then it is mostly only going to be one:

#1 a) 4 + 2 b) 6 * 17 c) 102 / 9
#2 a) 3 + 6

Thread #2 has contributed by calculating 3 + 6 = 9, used in step C by thread #1, saving it one step. But that is as far as parallelism will usefully get here. While thread #2 could calculate 17 / 9 while #1 is doing 6 * 17, doing that would be pointless, because you now have two different paths to the same goal that cannot be recombined. I.e., #2 could keep working:

b) 17 / 9 c) 1.888 * 6

And end up with the same result as thread #1 (11.333), but they have not helped one another beyond step A, therefore having two of them pursue this goal is a waste of time.

(Note that this example is not a literal one; it's intend to demonstrate a logical principle. The scale on which tasks are threaded in user code is much larger, but you don't need a real lesson in multi-threaded programming in order to grasp the idea here.)

Exploiting multiple processors requires code that is written to do it. You cannot simply take anything and say, "oh use all 4 cores and do it faster!". That's not what would happen. Logically, a lot of (..or most) problems and tasks involve steps that cannot happen in parallel, they must happen in sequence.


1. But see Felix Dombek's comment below; I am not an expert on AI. It may also be worth noting that as per Peter Corde's comments, contemporary instruction sets and processors can be exploited by the OS to optimise very finely grained things in a parallel manner, and hardware pipelines do this as well, albeit not across cores (a single core has more than one thing going on, operating on the stream of instructions at various points before their final execution). I was trying to stick to topic of user threads here as I think that is more or less what you are getting at.

6
  • 4
    I've written a lot of parallel numerical code, and this is a bit misleading as to the details. You don't parallelize at the level of individual arithmetic operations like this. (If we expand beyond Raspberry Pi, some compliers and processors will already parallelize some of that even outside of threading structures anyway.) You parallelize whole tasks in larger chunks.
    – Brick
    Commented Nov 22, 2017 at 4:51
  • 5
    @Brick "You don't parallelize at the level of individual arithmetic operations like this." -> Of course you don't, but I'll make it more explicit that this is an analogy, not a lesson on nuts and bolts multi-threaded programming.
    – goldilocks
    Commented Nov 22, 2017 at 6:25
  • 4
    The parallelism in the computation you use as an example is so localized that it will create instruction-level parallelism in a program that calculates it, and CPUs with out-of-order execution can exploit that parallelism on their own. Commented Nov 22, 2017 at 8:15
  • 2
    RPi3 uses an in-order 2-wide superscalar en.wikipedia.org/wiki/ARM_Cortex-A53, so with careful instruction scheduling a compiler can still exploit the ILP by putting two add instructions next to each other so they can both run in the same clock cycle. The following multiply and divide rest will be serialized by data dependencies, though, as you point out. Commented Nov 22, 2017 at 8:15
  • 1
    Determining parallelizable parts does not necessarily require a strong AI. In the "general" sense, it might; but it is easily imaginable that computers could use some heuristic approach which mostly works in many practical cases. Like, a computer didn't prove Fermat's last theorem, but there certainly are theorem prover programs. Note that modern compilers for programming languages already do lots of code rearrangement as part of their optimization steps, which involves reasoning over parallelizable parts. Commented Nov 22, 2017 at 15:40
8

No for python.

Other people are suggesting you to look into threading, which is a valid answer for most languages, but they didn't take into the account that you are using python.

The python GIL does not allow you to effectively make use of multiple cores.

1
  • 5
    The GIL makes it slightly more difficult to use all 4 cores. In no way does it make it impossible, or even really that challenging.
    – Fake Name
    Commented Nov 22, 2017 at 3:26
5

Using multiple cores requires explicitly exposing thread-level parallelism to the OS, which usually requires the programmer to write a multi-threaded program. (Or to run a single-threaded program multiple times on different inputs, like compiling with make -j4)

Compilers for some languages support auto-parallelization, though. For example, C or C++ with OpenMP can compile an ordinary for() loop into a program that starts multiple threads.

#pragma omp parallel for
for(int i = 0; i < 1000000; ++i)
{
   A[i] = B[i] * constant + C[i];
}

But still, this has to happen when you wrote or compiled the program. There is no way for current hardware and OSes to use multiple cores to speed up a single-threaded program.


Related: How does a single thread run on multiple cores?: answer: they don't. But there are other kinds of parallelism, like Instruction-level parallelism that a single CPU core finds and exploits to run a single thread faster than one instruction at a time.

My answer on that question goes into some of the details of how modern CPUs find and exploit fine-grained instruction-level parallelism. (Mostly focusing on x86). That's just part of how normal CPUs work, by having multiple instructions in flight at once, and isn't something you need to enable specially. (There are performance counters that can let you see how many instructions per clock your CPU managed to run while executing a program, though, or other measures.)

Note that RPi3 uses in-order ARM Cortex-A53 CPU cores. Each core is 2-wide superscalar (2 instructions per clock as ILP allows), but can't reorder instructions to find more instruction-level parallelism and hide latency.

Still, the CPU is pipelined, so the total number of instructions in flight (from fetch and decode all the way to the write-back stage at the end of the pipeline) is significant. When data dependencies don't limit things, there can be 2 instructions in each pipeline stage that the CPU is working on, with a throughput of 2 instructions per clock. (That's what 2-wide means.)

It can't execute instructions out of order, but with careful instruction ordering (usually by a compiler) it can still hide the latency of an instruction that takes multiple cycles for its output to be ready. (e.g. a load even if it hits in cache or a multiply will take multiple cycles, vs. an add being ready the next cycle). The trick is to order the asm instructions so there are multiple independent instructions between the one that produces a result and the one that uses it.

Having software (a compiler) statically schedule instructions is more brittle than having hardware that can reorder internally while preserving the illusion of running in program order. It's very hard for compilers to do as good a job as even a small out-of-order window for reordering instructions because cache-misses are unpredictable, and it's hard to analyze dependency chains across function calls at compile time. And the number of registers is limited without hardware register-renaming.


All of this is small comfort when your code runs slower than you'd like. Sure there's a lot of cool stuff under the hood in a Cortex-A53, but there's more cool stuff under the hood in a Cortex-A57 (like out-of-order execution of up to 3 instructions per clock), and even more in a big x86 CPU like Skylake (not to mention the clock-speed differences).

Cortex-A53 is pretty fantastic compared to a https://en.wikipedia.org/wiki/Classic_RISC_pipeline like original MIPS that you'd learn about in computer-architecture class, but by modern standards it's pretty low-end.

6
  • 1
    " There is no way for current hardware and OSes to use multiple cores to speed up a single-threaded program." is not STRICTLY true. For instance, in a single threaded Java program, Java can do all it's GC and run-time analysis/compiling on additional CPU cores. The runtime analysis is a big deal because it can decide to make some optimizations based on running code paths without costing your "single thread" anything and can speed it greatly with what it learns from the analysis. In general though your point is a good one.
    – Bill K
    Commented Nov 22, 2017 at 17:12
  • @BillK To be fair, the "program" in that context is java, not myapp.jar, and it certainly isn't single threaded.
    – goldilocks
    Commented Nov 22, 2017 at 18:52
  • 1
    True, I was just pointing out that depending on how the runtime was designed the "code you write", even though single threaded, can take advantage of extra cores without explicitly coding it as a multi-threaded app. Python could supply a more powerful runtime as well but it would be kind of pointless. It's not a huge jump anyway--I think even java only uses like an extra 1/2 core to help out with a single threaded app.
    – Bill K
    Commented Nov 22, 2017 at 22:26
  • "There is no way for current hardware and OSes to use multiple cores to speed up a single-threaded program." and immediately after that you explain how hardware executes instructions in parallel. Commented Nov 23, 2017 at 15:18
  • 3
    @ThomasWeller Yes, but to be picky processor pipelining does not use multiple cores; it is contained in one core, but it allows for work on multiple instruction streams. I.e., it is a form of parallelism, but it is not a form of multi-core threading.
    – goldilocks
    Commented Nov 23, 2017 at 16:57
4

This is not how CPUs work... at all.

As it currently stands, your CPU is perfectly capable of running at 100% usage, assuming that it's not being throttled due to temperature related issues at 80 degrees Celsius or more. That being said, you don't (generally) want to see your CPU pegged at 100%. If you're routinely at 100% CPU utilization, you likely have too much for your processor to handle. This will cause stuttering and a generally unhappy user experience.

To compare with something more physical, your CPU utilization is a lot like a car. The car is likely capable of going 100 mph, but there's a good chance your speedometer reads something significantly under that. When in town, you may never be able to get about 25 mph. That doesn't however change that the car can go 100 mph. You simply haven't pushed on the accelerator hard enough.

If you simply make the RPi do more things (push more on the accelerator), you'll see the CPU utilization figure go up. For example, watch the CPU utilization when you run the command yes in a terminal window (Remember that ctrl+c ends terminal commands). This will increase your CPU by 25% as it maxes out one of your four CPU cores.

3
  • 5
    I think this answer is misleading where is say you generally don't want your CPU running at 100% utilization. There are plenty of numerically intensive applications where you absolutely want 100% utilization because you've dedicated the machine (or machines) to the calculation. To get true supercomputer time, you often have to prove that your code is optimized well enough to do this, otherwise they'll deny you as a waste of resources. If you have a Pi cluster, you're not getting super computer performance, obviously, but that might make it more critical to maximize use, not less!
    – Brick
    Commented Nov 22, 2017 at 4:39
  • 3
    I kind of agree with Brick in the sense that it seems implied here that if a processor is at 25%, it's because it is to conserve gas or obey the speed limit ;) or to be polite and not hog resources. You might want to make it clearer that it's generally because whatever task is waiting on I/O much of the time. Things that can run a single core all the way up will. What (ideally) keeps this from disrupting the user interface is time slicing -- but realistically, it is still pretty easy to jam up a small single core machine.
    – goldilocks
    Commented Nov 22, 2017 at 6:32
  • 100% CPU utilization generally does not cause poor UX. Even 1000% can be good enough as most programs are not limited by the CPU but by other factors. The only programs that become slow due to an extreme CPU load are the programs that are actually using the CPU all the time.
    – Oskar Skog
    Commented Nov 23, 2017 at 10:21
4

The other answers do give good detail, but don't seem to address your question(s) specifically.

  1. Yes, if the program (and the operating system) are programmed to account for multiple cores. ('Threading' is the term in programming here)
  2. The machine uses as much or as little of each core as it needs to, to complete the task. so there is no need to change anything.
  3. You can set limits on maximum usage, but there isn't a need to in normal use. have a look at answers here :- https://unix.stackexchange.com/questions/151883/limiting-processes-to-not-exceed-more-than-10-of-cpu-usage

N.B :

If you are looking to improve the performance of the pi overall, you might want to look into Overclocking. This allows the CPU run at a faster rate. The downsides are increased heat production, lower lifetime of the processor, and increase power consumption.

2

If possible I would parameterize the script and execute them in separate Python processes. For example:

cat parameters.txt | xargs -n1 -P4 python run.py

An other alternative is the already mentioned multiprocessing library, which lets you fork-and-join python processes. But that also requires you to have a list of parameters (such as a filename) for which you want calculations to be run.

2
  • First part: Yes, presuming the problem at hand is embarrassingly parallel. Commented Nov 23, 2017 at 12:17
  • Ahaa true, I was familiar only with multiprocessing's processing pool map but apparently it also has many quite sophisticated shared-memory constructs.
    – NikoNyrh
    Commented Nov 23, 2017 at 14:18
1

If you want to test your RPI. You can run stress as in here, then you can see how your CPUs are being used with htop. This is useful because you can see if your power source is enough, if it is not enough your RPI will try to use too much current (amperage) and it will shutdown.

On the other hand, if you want to use python scripting, you should see joblib which works great when you want to parallelize processes, and thus you will be using the number of processors you wish.

1

I think OP might not fully understand the concepts of multi-core/multi-thread programming and how difficult to fully utilize 100% of multi-core unless the algorithm can be easily made into an embarrassingly parallel problem.

For more info, you can read more about the well known article title "The Free Lunch Is Over" http://www.gotw.ca/publications/concurrency-ddj.htm

0

Although all these answers are right in different ways it is true that the operating system will automatically use the different cores to spread the load. You can see this with a simple python program (temp.py say)

while True:
  x = 1.0

open a terminal from your RPi desktop and type $ top which will show processor work. Then open another terminal and python3 temp.py and you will see a python3 job rise to 100% processor time. Then open another terminal and repeat the process and see how you move up to 400%. So at one level as @Shadow commented it is that simple and it is the default. However designing programs that can use the parallel processing is non-trivial as others have explained.

0

The answer is a resounding YES! You simple have to write your program to recognize them and use them. Programs that do this can use the cores. I write mine to do this in Java and thus I can.

The above answers from Python developers have a very limited concept of this answer and so can be very confusing but the answer is YES and only YES!

1
  • Can you please elaborate?
    – SDsolar
    Commented Jun 18, 2018 at 20:09
0

Since the OP did not specify python in his question, I would like to suggest two more modern languages that work fine on the Raspberry Pi and have very easy ways to use concurrency.

My current favorite is the Rust language. I have written and compiled programs on the Pi. Rust is nice in that it prevents many types of pointer and race-condition bugs, which makes writing concurrent code both easier and safer. Rust is intended a systems programming language, but it can do pretty much anything C can do.

Another such language is Go (also called Golang to make it easier to search for). Go was created by the Google team, and is a reasonably mature language. It is easy to make coroutines in Go, which they call "Go routines."

Both of these languages can compile code on the Raspberry Pi, even the Pi Zero. However, they can both be cross-compiled from a faster computer which is nice for large programs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.