Why is a PC so fast compared to BeagleBoard? - Page 1
Forum section: electronics / general

author: Manx
author_rank: Contributor
timestamp: August 09, 2019, 06:32:05 pm
content: I have some code with trigonometric functions and matrix multiplications. Floating point calculations are single precision.When I run one calculations cycle on 180 MHz STM32 F4, it takes 145 us.When I run it on 1 GHz PocketBeagle Cortex A8 it takes 50us.But when I run it on my laptop with 1.8 GHz 3rd gen Core i5, it takes 1.8 us.Why?? It seems fine that Beagle is 3 times faster than STM32. But why is the laptop 30 times faster than Beagle, being only two times faster??

author: ataradov
author_rank: Super Contributor
timestamp: August 09, 2019, 06:44:42 pm
content: Caches primarily, then effective branch prediction and speculative execution.Compare the disassembled code. For matrix multiplication, compiler may have used SSE instructions on X86, which would make things multiple times faster right away.

author: ogden
author_rank: Super Contributor
timestamp: August 09, 2019, 06:50:00 pm
content: Flash memory access alone acts like speedbrake for MCU, not to mention that embedded ARM cores are optimized for low power, not speed. Intel CPU's are heavily performance-optimized. - Deep pipelines, out of order execution, huge instruction and data cache memories. Why you think CPU of your laptop needs 35W of power? - Just to act like heater or what?

author: coppice
author_rank: Super Contributor
timestamp: August 09, 2019, 06:51:04 pm
content: I suspect that either you have something odd in the compile options for the A8, and/or the Beagleboard is not running at 1GHz. Depending how you set up a Beagleboard, it may deault to a low clock rate, and require you to take action to push the clock rate up to 1GHz. A Core i5 will be a lot faster than an A8, but the speed ratio you have seen is too big to be representative.

author: ataradov
author_rank: Super Contributor
timestamp: August 09, 2019, 06:52:27 pm
content: It really depends on the generated code. X86 floating point instruction set is much better than A8 FP ISA.

author: ogden
author_rank: Super Contributor
timestamp: August 09, 2019, 07:10:51 pm
content: Quote from: coppice on August 09, 2019, 06:51:04 pmIt could be so. Stm32 results compared to Cortex A8 does not make sense as well.

author: Manx
author_rank: Contributor
timestamp: August 09, 2019, 07:37:50 pm
content: I simply useCode:g++ -Ofast RobotKinematicsMCU.cpp -o testIt's the same withCode:g++ -Ofast -mcpu=cortex-a8 -mfloat-abi=hard -mfpu=neon RobotKinematicsMCU.cpp -o testWhen I check cpu frequency withCode:cpufreq-infothe governor is set to "performance" and 1 GHz is shown to be running all the time.Basic question: How can I see disassembled code?

author: rstofer
author_rank: Super Contributor
timestamp: August 09, 2019, 07:38:37 pm
content: It's even simpler than the explanations above: Power - how much heat can you dissipate. To switch in zero time takes infinite energy and, as switching speed increases, so does power. Power also increases with complexity. The more logic you have switching, the more power you need to deal with.I bought a Raspberry Pi 4 - it's a pretty nice little machine. I don't expect it to compete with my 4+ GHz I7-7700k water cooled tower. There's a reason the Pi wall wart is 5V 3A (15 Watts) and my tower is around 500W. That tower had better be faster than the Pi!The speed power product (a measure of gate switching delay and gate power dissipation) is improving all the time. I recall the VP of a company I worked for telling me to not bet against technology. This was in the mainframe era and today my tower is faster and has more memory.Yes, the architectural features matter but they all point toward increasing power dissipation.

author: rstofer
author_rank: Super Contributor
timestamp: August 09, 2019, 07:46:00 pm
content: Quote from: Manx on August 09, 2019, 07:37:50 pmgcc -S ...or study up onobjdump -d

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 09, 2019, 09:12:29 pm
content: Yeah. All good points. When doing such comparisons, you have to determine how much it is affected by memory/cache access times, and how much by the FPU itself.And that said, I don't know much about the FPU of a Cortex A8. I would expect it not to put out as many operations per cycle on average than the FPU of a Core i5, but I may be wrong.

author: Manx
author_rank: Contributor
timestamp: August 09, 2019, 11:59:49 pm
content: Thank you guys for your explanations. The main takeaway is then, that the results I got are to be expected. So I don't have to bother with moving to Beagle since the speed increase won't justify the effort. Fine with meBut I must say, seeing such a big difference between Beagle and a laptop really surprised me. Well, but now I know.

author: james_s
author_rank: Super Contributor
timestamp: August 10, 2019, 12:08:16 am
content: When you say something is x times faster it sounds like you are looking only at the clock speed. There is a LOT more to the performance of a CPU than the clock speed. The number of cores, the architecture of the CPU and of the system as a whole and the peripherals around it have an enormous effect on performance. Clock speed doesn't really tell you much anymore, it only matters when comparing like to like.

author: IanB
author_rank: Super Contributor
timestamp: August 10, 2019, 12:11:48 am
content: No one has mentioned it yet, but the Intel processors in laptops have highly optimized floating point capabilities compared to simpler micros.

author: ogden
author_rank: Super Contributor
timestamp: August 10, 2019, 12:27:49 am
content: Quote from: IanB on August 10, 2019, 12:11:48 amIn what sense Intel have highly optimized floating point capabilities compared to simpler micros (ARM Cortex A8)? BTW mentioned ARM have NEON SIMD tech which allows up-to 4*32bit parallel float operations. There's open source libraryhttp://projectne10.github.io/Ne10/

author: rsjsouza
author_rank: Super Contributor
timestamp: August 10, 2019, 12:34:41 am
content: Quote from: SiliconWizard on August 09, 2019, 09:12:29 pmAssuming the code is actually oprimized and encoding the floating point instructions (and not emulated code), there'a another aspect: the FPU on an A8 shares its registers with its matrix math engine (NEON), thus reducing the performance of matrix operations that also use float. If you run the same on an A9 or A15 (BeagleBoard X15) you should have much more edge.There was a wiki article at TI that talked about that. It is an inherent feature of the A8 cores, not only TI (IIRC).(edit) I found the article. It is slightly different than I recall - the precision is limited with VFP+NEONhttp://processors.wiki.ti.com/index.php/Using_NEON_and_VFPv3_on_Cortex-A8

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 10, 2019, 01:49:17 am
content: Yet another point, and still related to memory access.You will get significant performance penalty if the location in memory of the variables/arrays you are working on are not ideally aligned for the architecture in question. Ideal alignment depends a lot on the CPU architecture, and if not explicitely defined (through GCC attributes for instance) in code, can lead to very suboptimal results, which would not really reflect each CPU's capabilities.All CPUs supporting some form of SIMD have specific alignment requirements to make the most of them.

author: Berni
author_rank: Super Contributor
timestamp: August 10, 2019, 06:26:59 am
content: Yep your beagleboard code is likely not that well optimized for the given hardware.You need to look down into the instruction set what that CPU likes to do and make sure the C compiler does it in such a way. The NEON extensions can be very powerful for doing number crunching but will not tend to be used by the C compiler due to the careful memory layout needed for it to work. The compiler is likely using the standard single cycle multiply function that you might find in a STM32F4. As for why its not as fast as the clock speed claims is likely because your data is stored in RAM in such a way that the CPUs data cache has trouble loading it efficiently.When doing very repetitive math its also important what you have around your raw math operations, you can spend a lot of CPU time simply moving data around or shoveling it into the CPU registers to be worked on, or even just executing the for loop that is around it.As for why Intel is so speedy its down to the superior parallel number crunching capabilities and its heavily pipelined execution that might shove multiple instructions trough the CPU core in a single clock cycle. The branch prediction might be working its magic on those repetitive loops, it has faster RAM and has a LOT more cache so all the data likely fits into its cache. Its also possible the C compiler does a better job at compiling your particular code implementation onto that instruction set.If you need the speed then there are little Intel Atom single board computers out there. They won't quite have the performance of a i5/i7 at the same clock speed but its still gonna be pretty speedy while using a more reasonable amount of power.

author: magic
author_rank: Super Contributor
timestamp: August 10, 2019, 07:21:56 am
content: perf stat -d ./testOn all 3 platforms.

author: Manx
author_rank: Contributor
timestamp: August 10, 2019, 12:08:59 pm
content: No much luck with perf. It says it won't work on my laptop because of the kernel version, and on Beagle it showsCode:Performance counter stats for './test':48877.972638 task-clock:u (msec) # 0.997 CPUs utilized0 context-switches:u # 0.000 K/sec0 cpu-migrations:u # 0.000 K/sec77 page-faults:u # 0.002 K/sec<not supported> cycles:u<not supported> instructions:u<not supported> branches:u<not supported> branch-misses:u<not supported> L1-dcache-loads:u<not supported> L1-dcache-load-misses:u<not supported> LLC-loads:u<not supported> LLC-load-misses:u49.024961877 seconds time elapsedThe code is indeed not optimized for any specific platform. But a big part of the execution time, as I checked with pin toggling on STM32, is just spent on standard trigonometric functions. And I think that -Ofast does loop unrolling.I quickly checked Intel Atom on google and it's probably a great thing, but I'm looking for something for which I can design my own board. Atom boards certainly don't look like anything close to that

author: splin
author_rank: Frequent Contributor
timestamp: August 10, 2019, 01:39:20 pm
content: Take a look athttp://gruntthepeon.free.fr/ssemath/neon_mathfun.htmlcomparing vector trigonometric performance on ARM NEON and Intel Atom using their own optimized trig code. Fundamentally not much difference in cycles per operation.They also tested their SSE2 implementation here:http://gruntthepeon.free.fr/ssemath/

author: rsjsouza
author_rank: Super Contributor
timestamp: August 10, 2019, 05:29:18 pm
content: Quote from: splin on August 10, 2019, 01:39:20 pmThanks for sending this, although the Pandaboard uses a dual Cortex A9 (OMAP4430), which does not have the same bottleneck as the A8.Having the code, it is easy to migrate to a BeagelBone or X15 - I might do that next week just for kicks.

author: NiHaoMike
author_rank: Super Contributor
timestamp: August 10, 2019, 07:42:15 pm
content: The Beaglebone is also quite old, so it's not going to perform particularly stellar even compared to other embedded Linux platforms like Raspberry Pi. It's still pretty unique in its capabilities, however, with its support for simultaneous USB host and device (not as big of a deal now with the Pi 4 also supporting that) and the I/O accelerator that, among other things, can be used as a logic analyzer.

author: magic
author_rank: Super Contributor
timestamp: August 10, 2019, 08:22:32 pm
content: Quote from: Manx on August 10, 2019, 12:08:59 pmThat's indeed very little luckQuote from: Manx on August 10, 2019, 12:08:59 pmAFAIK trig functions are implemented by polynomial approximation so strictly CPU bound. Rather out of luck again, unless your standard library is completely inefficient garbage.Perhaps some faster and slightly less accurate implementations can be found. Or find the relevant polynomials and roll your own, using SIMD to compute sinus of four numbers in parallel. These days they could frankly provide such stuff in standard libraries.

author: rsjsouza
author_rank: Super Contributor
timestamp: August 10, 2019, 10:15:43 pm
content: Quote from: NiHaoMike on August 10, 2019, 07:42:15 pmI think the Pi4 is the only one that has a performance edge - the Pi3 versions are quite comparable in speed, no?

author: NiHaoMike
author_rank: Super Contributor
timestamp: August 10, 2019, 10:33:15 pm
content: Quote from: rsjsouza on August 10, 2019, 10:15:43 pmThe Beaglebone is a single core A8 while the Pi 3 is a quad core A53. What the Beaglebone has that the Pi doesn't is a pair of I/O accelerators that are essentially microcontrollers with fast access to the GPIO and RAM. That's what is used for the logic analyzer functionality.The Odroid N2 is in a similar class as the Pi 4. Then there's the Jetson Nano, basically a lower end version of the Shield TV.

author: hamster_nz
author_rank: Super Contributor
timestamp: August 10, 2019, 11:15:43 pm
content: Revisit your code with the knowledge that sin() and cos() is very expensive on your platform, and are to be avoided as much as possible.On a hobby DSP project using a lookup table made things 4x faster.

author: magic
author_rank: Super Contributor
timestamp: August 11, 2019, 08:48:04 am
content: Another big weakness of most ARM boards in comparison with x86 PC is memory bus width, and perhaps frequency too, both limiting RAM bandwidth.Not the limiting factor in this case, though.

author: rstofer
author_rank: Super Contributor
timestamp: August 11, 2019, 04:55:42 pm
content: Another possible speedup is in pulling loop invariant code outside the loop.do i = 1, 100ohmega(i) = 2.0 * Pi * f(i) // or some such ** BAD **end doHere the 2.0 * Pi is loop invariant and should be pulled out of the loop. Sometimes the compiler will do it, other times not. Sometimes it is not obvious what is loop invariant because there is a bunch of code inside the loop.twoPi = 2.0 * Pi // ** BETTER **do i = 1, 100ohmega(i) = twoPi * f(i)end doLookup tables for trig functions is a good idea. You can even do a wee bit of interpolation between value if necessary. You only need the table to cover 0..Pi/2 (90 degrees) so it doesn't necessarily have to take a lot of space. You can also manipulate the argument for cos() such that it can also use the same table. You can improve on the idea by not adding 3*Pi/4 but rather just start your index 3/4 the way through the table and deal with wrap-around. Much faster...

author: ralphrmartin
author_rank: Frequent Contributor
timestamp: August 14, 2019, 06:41:21 pm
content: Quote from: ataradov on August 09, 2019, 06:44:42 pmShouldn't be any branch prediction in trig function calculation, or matrix multiplication.

author: coppice
author_rank: Super Contributor
timestamp: August 14, 2019, 06:55:35 pm
content: Quote from: rstofer on August 11, 2019, 04:55:42 pmModern compilers are usually pretty good at doing that for themselves, as long as you have optimisation enabled.

author: Manx
author_rank: Contributor
timestamp: August 30, 2019, 09:31:18 am
content: Fun fact. I bought myself a new Nucleo board, H743ZI. It's 400 MHz Cortex M7. The same test that took 145 us on 180 MHz Nucleo F4 and 50 us on 1GHz Cortex A8 PocketBeagle, now takes... 45 us.So without bothering with an operating system, boot up time etc, I have calculation speed the same as on a 2.5 times faster processor. And this happens with standard libraries and generic code, without pondering if I maybe could do some highly optimized custom code for a specific processor. So to me it looks like Cortex A8 is not that good, but Cortex M7 is absolutely great.As for using lookup tables or other faster method instead of standard trig functions, I don't think it's really an option. The calculations are for kinematics of a 6 DOF robotic arm, and I need precision, especially around singularities. Rather, I'm considering if I should maybe use double precision calculations. That's one of the advantages of M7 over M4. Still, I'm not rushing into it since double precision FPU is slower than the single precision one. Anyways, with the current configuration I think I could easily get 10 000 kinematics calculations (i.e. 10k points in space processed) per second in the final application, which I take as a very good result.

author: tszaboo
author_rank: Super Contributor
timestamp: August 30, 2019, 10:18:39 am
content: I cant believe this is the second page and nobody mentioned it:Pipeline lengthInstructions per cyclecortex A7A15It just calculates more stuff at the same time. Clock is an almost meaningless value alone.

author: ogden
author_rank: Super Contributor
timestamp: August 30, 2019, 04:42:18 pm
content: Quote from: NANDBlog on August 30, 2019, 10:18:39 amIncorrect. In thesecond reply of this threadI did mention deep pipelines and out of order execution. That obviously means better instructions/cycle ratio:Quote from: ogden on August 09, 2019, 06:50:00 pm

author: magic
author_rank: Super Contributor
timestamp: August 30, 2019, 09:33:44 pm
content: Pipelining is evil, its value is enabling higher clock speeds by reducing the time it takes to process one pipeline step.A 2-stage "decode, execute" pipeline with all the reordering tricks and doubled/tripled execution units would be faster at the same clock speed, thanks to less instructions being flushed on mispredicted branches. But such a thing will never run at the same clock as the deeply pipelined cores.Pentium 4 was famously a deeply pipelined core, designed to take advantage of multi-GHz clocks that Intel hoped to achieve. It had its ass kicked by the simpler Athlon XP and Intel ditched it in favor of new cores derived from Pentium III.