hippy
Posts: 8959
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Avoiding 100% CPU usage

Wed Nov 25, 2020 4:36 pm

If one has a bare metal assembly language loop, for example when waiting for a GPIO pin to be asserted; how does one prevent that using 100% CPU, raising the SoC's temperature ?

User avatar
mooblie
Posts: 233
Joined: Fri Oct 14, 2016 2:07 pm
Location: The Scottish Highlands

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 4:39 pm

Make a NOP loop that does nothing for a millisecond or so, and call it each time before you poll the GPIO pin?

Or learn about interrupts?

hippy
Posts: 8959
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 5:15 pm

I did not think using a NOP would reduce the CPU usage from 100%, but if it does that is ideal for me.

User avatar
rpdom
Posts: 18012
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 5:45 pm

I guess the NOP instruction will use very little of the CPU's power. There are no register moves involved. No calculations. No conditions to check. The CPU will just sit there for one clock cycle doing nothing.
Unreadable squiggle

User avatar
jahboater
Posts: 6533
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 6:43 pm

rpdom wrote:
Wed Nov 25, 2020 5:45 pm
I guess the NOP instruction will use very little of the CPU's power. There are no register moves involved. No calculations. No conditions to check. The CPU will just sit there for one clock cycle doing nothing.
Yes.
I tried a simple loop:

Code: Select all

asm volatile ( "1: nop; b 1b" : );
It barely raises the CPU temp on my Pi4 with no heat sink - 4 degrees or so.
Run it on all four cores and it goes up by another 9 or 10 degrees.

You will have to check the time of course, or arrange for an interrupt.
Pi4 8GB and Pi4 4GB running Raspberry Pi OS 64-bit

hippy
Posts: 8959
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 6:54 pm

Thanks. I'll likely just add a block of NOP's to have a better ratio of 'doing nothing' to 'doing things'.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 27941
Joined: Sat Jul 30, 2011 7:41 pm

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 9:32 pm

Do our cores have the WFE instruction? On some devices that puts a core to sleep until a wake up event. Even less power than a NOP.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

cleverca22
Posts: 2508
Joined: Sat Aug 18, 2012 2:33 pm

Re: Avoiding 100% CPU usage

Wed Nov 25, 2020 11:37 pm

jamesh wrote:
Wed Nov 25, 2020 9:32 pm
Do our cores have the WFE instruction? On some devices that puts a core to sleep until a wake up event. Even less power than a NOP.
https://github.com/raspberrypi/tools/bl ... ub7.S#L178

the arm stub that holds the other 3 cores until the OS is ready to take over, is already using wfe to idle them
i would expect rpi1 to at least have WFI instead, since there are no real events

LdB
Posts: 1665
Joined: Wed Dec 07, 2016 2:29 pm

Re: Avoiding 100% CPU usage

Thu Nov 26, 2020 1:05 am

Use the GPIO interrupt there is no need to poll the GPIO you are clearly looking for a level change

hippy
Posts: 8959
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Avoiding 100% CPU usage

Thu Nov 26, 2020 1:00 pm

cleverca22 wrote:
Wed Nov 25, 2020 11:37 pm
jamesh wrote:
Wed Nov 25, 2020 9:32 pm
Do our cores have the WFE instruction? On some devices that puts a core to sleep until a wake up event. Even less power than a NOP.
i would expect rpi1 to at least have WFI instead, since there are no real events
Adding WFE or WFI causes GAS/GCC to generate executable code for ARMv6KZ - Not sure if that's compatible with BCM2708.
LdB wrote:
Thu Nov 26, 2020 1:05 am
Use the GPIO interrupt there is no need to poll the GPIO you are clearly looking for a level change
In some cases it is reading all pins, masking and comparing with a match , so I presume that needs to be polled, and it's a lot easier to code -

while ( ((*pins) & mask) != match ) { nap(); }

User avatar
Paeryn
Posts: 3153
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Avoiding 100% CPU usage

Thu Nov 26, 2020 8:01 pm

hippy wrote:
Thu Nov 26, 2020 1:00 pm
cleverca22 wrote:
Wed Nov 25, 2020 11:37 pm
jamesh wrote:
Wed Nov 25, 2020 9:32 pm
Do our cores have the WFE instruction? On some devices that puts a core to sleep until a wake up event. Even less power than a NOP.
i would expect rpi1 to at least have WFI instead, since there are no real events
Adding WFE or WFI causes GAS/GCC to generate executable code for ARMv6KZ - Not sure if that's compatible with BCM2708.
WFI, WFE, SEV & SEVL are NOP-compatible hint instructions. They are actually encoded as MSR <spec_reg>, #imm instructions but with spec_reg set to nothing, this gives 256 possible instructions (with the instruction to execute identified by the imm value) where, if the processor doesn't support the instruction, it will be treated as a NOP (as with no registers set to update MSR will do nothing).
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

dwelch67
Posts: 971
Joined: Sat May 26, 2012 5:32 pm

Re: Avoiding 100% CPU usage

Fri Nov 27, 2020 10:19 am

I cant see how a nop and a gpio read will really be much different. There are still many signals changing to perform a nop, so what if the core doesnt touch registers it still does the fetches on a bus, which is ideally cached, but...do you have the i cache on, are you hitting dram, etc. the gpu is still running yes, etc etc. Can you even detect a power draw difference between the gpio loop and the nop loop?

If you want to reduce power on the arm then yes the wfi/wfe is the way to go, adding nops I cant see as actually measurable, just exercises more signals more signals changing state is where your power consumption comes from, granted they are not so much in parallel but in series, and other factors.

If this is a button or something you definitely do not want to use an interrupt to detect the level change. You want to either poll it and debounce or use a timer based interrupt and then poll periodically that way and put some debounce logic in there. Or use a timer to space out the gpio sampling instead of nops.

Since the arm is doing so little in either case polling or waiting on an interrupt, not sure you would be able to measure the power difference with the interrupt, maybe if the arm goes into a low power state but the chip is not completely idle and is still a big chip.

User avatar
MikeDB
Posts: 405
Joined: Sun Oct 12, 2014 8:27 am

Re: Avoiding 100% CPU usage

Fri Nov 27, 2020 11:19 am

I can't really see any problem with using a tight NOP loop - it will all be in the instruction cache so no memory access should take place. If you are concerned with power consumption then better to look if the clock could be reduced, peripherals turned off, etc.

LdB
Posts: 1665
Joined: Wed Dec 07, 2016 2:29 pm

Re: Avoiding 100% CPU usage

Fri Nov 27, 2020 2:18 pm

Usually there are other things the CPU could be doing than wasting time looping. Fine if you have nothing else to do who cares do whatever unless the OP clarifies whether there is other processing to be done it's all a guess.

hippy
Posts: 8959
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Avoiding 100% CPU usage

Fri Nov 27, 2020 4:27 pm

LdB wrote:
Fri Nov 27, 2020 2:18 pm
Usually there are other things the CPU could be doing than wasting time looping. Fine if you have nothing else to do who cares do whatever unless the OP clarifies whether there is other processing to be done it's all a guess.
This will be code which will do nothing other than loop/wait/stall until input pin levels are matched. There are no other tasks or anything else which needs to run, no other work to do.

Code: Select all

.macro	WaitFor	mask,match
        num     r1,\mask
        num     r2,\match
        num     r3,GPIO_LEV0
        add     r3,io
.1:     ldr     r0,[r3]
        and     r0,r1
        cmp     r0,r2
        bne     .1b
.endm

Return to “Bare metal, Assembly language”