Author Topic: Apples new M1 microprocessor  (Read 87649 times)

0 Members and 19 Guests are viewing this topic.

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23102
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #250 on: November 28, 2020, 01:44:13 pm »
Don’t forget the Google tax where they sell you a substandard product and fail to support it too!

Quick compiler update. Working on getting .net core CLR compiled on it. Looks like Microsoft are way behind the curve. Nowhere near ready even under Rosetta  :palm:

Edit: golang works under Rosetta and seems about the same speed as my ryzen single threaded on compiler performance.
« Last Edit: November 28, 2020, 01:49:48 pm by bd139 »
 

Offline nfmax

  • Super Contributor
  • ***
  • Posts: 1687
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #251 on: November 28, 2020, 03:23:14 pm »
You mentioned it's supposed to have peak throughput of 8 IPC. Are there any tools on OSX to measure it and see if it really makes a difference? From your experience designing CPUs / optimizing software / whatever you did (I suppose), where do you think may be the point of diminishing returns where going to a wider core just ceases making sense anymore?

8 IPC is not achievable on typical software, even with perfect branch predition.

I think it's useful on "inefficient" software such as that generated by JIT compilers, or languages which are doing bounds checking or reference count updating in parallel with the actual useful instructions.

Where did you get 8IPC from? I read it can (most likely) decode 8 instructions simultaneously, increasing the number of options available to the instruction reordering unit to dispatch to the various execution pipelines. This is not the same as dispatching 8 instructions per clock cycle
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 8060
  • Country: pl
Re: Apples new M1 microprocessor
« Reply #252 on: November 28, 2020, 05:56:23 pm »
High performance CPUs have plenty of execution resources, I suppose a machine with 8-wide decode should be able to get close to that on the backend too.

According to AMD, Zen can dispatch up to 10 µops in one cycle, and these are similar to RISC instructions. Of course they cannot be completely arbitrary µops, there isn't enough execution unit duplication for that, but an appropriate mix of pending instructions of different kinds could execute like that.
 

Offline Marco

  • Super Contributor
  • ***
  • Posts: 7744
  • Country: nl
Re: Apples new M1 microprocessor
« Reply #253 on: November 28, 2020, 06:09:25 pm »
The 4800U has effectively twice the number of cores.

Roughly the same size though, taking into account the node difference. Also IPC being such an enormously diminishing returns game, those little cores are far from useless if they aren't clock restricted.
« Last Edit: November 28, 2020, 06:19:45 pm by Marco »
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 8060
  • Country: pl
Re: Apples new M1 microprocessor
« Reply #254 on: November 28, 2020, 09:10:34 pm »
Here's some details about (apparently - I'm not familiar with ARM stuff) the most advanced core publicly unveiled by ARM to date:

https://fuse.wikichip.org/news/3543/arm-cortex-x1-the-first-from-the-cortex-x-custom-program/

It looks very similar to x86 stuff, even with pre-decoding into macro-ops and a dedicated macro-op cache. They say it can optimistically issue and retire up to 8 instructions in one cycle when running from the MOP cache.
 

Offline olkipukki

  • Frequent Contributor
  • **
  • Posts: 790
  • Country: 00
Re: Apples new M1 microprocessor
« Reply #255 on: November 28, 2020, 11:03:06 pm »
Nobody yet mentioned a storage controller and SSD performance  ::)

How it looks compare to 'old' world?
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23102
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #256 on: November 28, 2020, 11:18:08 pm »
About the same to be honest. 2100MB/s write,  2706MB/s read
 

Offline tooki

  • Super Contributor
  • ***
  • Posts: 15912
  • Country: ch
Re: Apples new M1 microprocessor
« Reply #257 on: November 29, 2020, 05:01:20 pm »
About the same to be honest. 2100MB/s write,  2706MB/s read
Depends on what you're comparing.

Arstechnica's review of the M1 MacBook Air (tested with 1TB SSD), as tested with Blackmagic disk speed test, shows the M1 Macbook Air having R/W of 3101/2707 MB/sec, vs. 2265/2024 for a 2020 Intel MacBook Pro and 1262/1281 for a 2020 Intel MacBook Air.
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23102
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #258 on: November 29, 2020, 05:27:13 pm »
Have attached my actual measurements this time.
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #259 on: November 29, 2020, 05:30:15 pm »
About the same to be honest. 2100MB/s write,  2706MB/s read

When people says "old", well ... "old" for me means 60Mbyte/sec, two order of magnitudes slower, hence I would for sure appreciate the speedup  :D
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline olkipukki

  • Frequent Contributor
  • **
  • Posts: 790
  • Country: 00
Re: Apples new M1 microprocessor
« Reply #260 on: November 29, 2020, 09:30:58 pm »
60Mbyte is in a vintage category  :horse: when you are not in the rush and appreciate Sound of Hard Drive  :-DD
 
The following users thanked this post: DiTBho

Offline olkipukki

  • Frequent Contributor
  • **
  • Posts: 790
  • Country: 00
Re: Apples new M1 microprocessor
« Reply #261 on: November 29, 2020, 09:42:59 pm »
Have attached my actual measurements this time.
Is yours one 256GB?

P.S.
I'm expecting to triple your measurements when 980 Pro 1TB will come into a house  :P
« Last Edit: November 29, 2020, 09:49:50 pm by olkipukki »
 

Offline olkipukki

  • Frequent Contributor
  • **
  • Posts: 790
  • Country: 00
Re: Apples new M1 microprocessor
« Reply #262 on: November 29, 2020, 09:46:56 pm »


Arstechnica's review of the M1 MacBook Air (tested
Indeed, Air M1 is a real winner here.

Not sure what is a reason to buy M1 pro 13" right now, a bit better screen?!  :-//
 

Offline tooki

  • Super Contributor
  • ***
  • Posts: 15912
  • Country: ch
Re: Apples new M1 microprocessor
« Reply #263 on: November 29, 2020, 09:57:00 pm »


Arstechnica's review of the M1 MacBook Air (tested
Indeed, Air M1 is a real winner here.

Not sure what is a reason to buy M1 pro 13" right now, a bit better screen?!  :-//
The Air has no fan, so will begin to thermally throttle under sustained high load. Macbook Pro and Mac mini have a small fan and can sustain maximum performance indefinitely.
 

Offline bd139

  • Super Contributor
  • ***
  • Posts: 23102
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #264 on: November 29, 2020, 10:35:42 pm »
Have attached my actual measurements this time.
Is yours one 256GB?

P.S.
I'm expecting to triple your measurements when 980 Pro 1TB will come into a house  :P

Yeah. I’ve got a 1TB 970 pro here in my Windows box. Will test that tomorrow.
 

Offline NiHaoMike

  • Super Contributor
  • ***
  • Posts: 9771
  • Country: us
  • "Don't turn it on - Take it apart!"
    • Facebook Page
Re: Apples new M1 microprocessor
« Reply #265 on: November 30, 2020, 12:20:26 am »
When people says "old", well ... "old" for me means 60Mbyte/sec, two order of magnitudes slower, hence I would for sure appreciate the speedup  :D
The only HDDs 1TB and above I'm aware of with a sequential speed less than 60MB/s are the SMR "cost optimized" ones.
Cryptocurrency has taught me to love math and at the same time be baffled by it.
Cryptocurrency lesson 0: Altcoins and Bitcoin are not the same thing.
BTC: 18813fu8LQEdDwH9YLM1ABed3XwCfeSeFi
 

Offline Berni

  • Super Contributor
  • ***
  • Posts: 5378
  • Country: si
Re: Apples new M1 microprocessor
« Reply #266 on: November 30, 2020, 06:55:20 am »
2GB/s and up sequential speeds are pretty much the norm thee days for decent NVME SSDs. The more difficult numbers to keep up is random access with a single queue, these are also what makes a SSD so snappy. You can get 2 GB/s sequential speeds out of a big enough array of spinning rust, but the random access speeds are going to be in the few MB/s and booting an OS off it will take forever just like one expects from a classical HDD. But once you get to the random access speeds the fastest SSDs are capable of even the driver overhead can have a significant effect.

CrystalDiskMark is a good tool that tests both sequential and random access, but its a Windows only thing. I remember getting similar sequential figures running a Windows 7 VM inside KVM on my NAS that keeps the disk image on a M.2 SSD (I think its a Samsung 970 Pro but not sure)
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 8060
  • Country: pl
Re: Apples new M1 microprocessor
« Reply #267 on: November 30, 2020, 11:16:18 am »
Does anyone have any tests they'd like run on the M1, and in particular source code? MacOS or Ubuntu code ...
Could you try the attached C++ file?
It runs several Fibonacci sequences in parallel to 20 million iterations (overflows, I know).
It should be compiled with GCC≥8.0 to respect the unroll pragma, which reduces loop counting overhead.

My older AMD system with GCC 10 scales linearly to 3 "gigainops"/GHz and then plateaus until it runs out of architectural registers at N=8 and progressively slows down to 1G/GHz (or worse for 16bit).

Skylake seems to hit 3~4G/GHz, but I'm not sure how much exactly because of turbo.

I tried it on a Cortex A15 too and got 1G/GHz at N=1 and 1.75 at N≥2. It probably could be 2 exactly, but the old-ass GCC 4.5 doesn't unroll the outer loop so some cycles are wasted counting iterations. For whatever reason it also starts to spills registers at N≥4, meh, I hope the 64bit Mac / Ubuntu will be better :P
 
The following users thanked this post: bd139

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6427
  • Country: nz
Re: Apples new M1 microprocessor
« Reply #268 on: November 30, 2020, 02:29:16 pm »
ThreadRipper 2990wx (4.2 GHz turbo)
Seems to hit 3.33 G/GHz, then plummets

==================== 16bit ====================
ff1b0mark 10000000*2 iterations 7 paralell... result 34862
10.291881 milliseconds 140000000 additions 13.602956 gigainops

f1b0mark 10000000*2 iterations 8 paralell... result 30480
20.060230 milliseconds 160000000 additions 7.975980 gigainops

==================== 32bit ====================
f1b0mark 10000000*2 iterations 7 paralell... result 647333934
9.965147 milliseconds 140000000 additions 14.048965 gigainops

f1b0mark 10000000*2 iterations 8 paralell... result 2580510480
20.051023 milliseconds 160000000 additions 7.979643 gigainops


==================== 64bit ====================
f1b0mark 10000000*2 iterations 7 paralell... result 2438629122182055982
9.980738 milliseconds 140000000 additions 14.027019 gigainops

f1b0mark 10000000*2 iterations 8 paralell... result 15963250478000600848
19.879080 milliseconds 160000000 additions 8.048662 gigainops


M1 Mac Mini, native ("gcc" is aliased to Apple LLVM), "3.2 GHz".
Scales somewhat sublinearly to 18.08 = 5.65 G/GHz at N=8, then continues to increase to 18.51 = 5.75 at N=14, then drops
No difference 16/32/64 bit so I'll just show 64 bit.

==================== 64bit ====================
f1b0mark 10000000*2 iterations 1 paralell... result 13524621355818544866
6.493208 milliseconds 20000000 additions 3.080142 gigainops

f1b0mark 10000000*2 iterations 2 paralell... result 8602498637927538116
6.491041 milliseconds 40000000 additions 6.162340 gigainops

f1b0mark 10000000*2 iterations 3 paralell... result 3680375920036531366
6.990208 milliseconds 60000000 additions 8.583436 gigainops

f1b0mark 10000000*2 iterations 4 paralell... result 17204997275855076232
7.247458 milliseconds 80000000 additions 11.038353 gigainops

f1b0mark 10000000*2 iterations 5 paralell... result 12282874557964069482
7.923459 milliseconds 100000000 additions 12.620751 gigainops

f1b0mark 10000000*2 iterations 6 paralell... result 7360751840073062732
8.440000 milliseconds 120000000 additions 14.218009 gigainops

f1b0mark 10000000*2 iterations 7 paralell... result 2438629122182055982
9.547209 milliseconds 140000000 additions 14.663971 gigainops

f1b0mark 10000000*2 iterations 8 paralell... result 15963250478000600848
8.864500 milliseconds 160000000 additions 18.049523 gigainops

f1b0mark 10000000*2 iterations 9 paralell... result 11041127760109594098
10.047375 milliseconds 180000000 additions 17.915127 gigainops

f1b0mark 10000000*2 iterations 10 paralell... result 6119005042218587348
11.037625 milliseconds 200000000 additions 18.119840 gigainops

f1b0mark 10000000*2 iterations 11 paralell... result 1196882324327580598
12.031625 milliseconds 220000000 additions 18.285144 gigainops

f1b0mark 10000000*2 iterations 12 paralell... result 14721503680146125464
13.026417 milliseconds 240000000 additions 18.424099 gigainops

f1b0mark 10000000*2 iterations 13 paralell... result 9799380962255118714
14.066792 milliseconds 260000000 additions 18.483248 gigainops

f1b0mark 10000000*2 iterations 14 paralell... result 4877258244364111964
15.126333 milliseconds 280000000 additions 18.510765 gigainops

f1b0mark 10000000*2 iterations 15 paralell... result 18401879600182656830
36.436875 milliseconds 300000000 additions 8.233417 gigainops

f1b0mark 10000000*2 iterations 16 paralell... result 13479756882291650080
38.526250 milliseconds 320000000 additions 8.306025 gigainops

f1b0mark 10000000*2 iterations 17 paralell... result 8557634164400643330
46.079083 milliseconds 340000000 additions 7.378619 gigainops

f1b0mark 10000000*2 iterations 18 paralell... result 3635511446509636580
47.268208 milliseconds 360000000 additions 7.616113 gigainops

f1b0mark 10000000*2 iterations 19 paralell... result 17160132802328181446
53.159250 milliseconds 380000000 additions 7.148333 gigainops

f1b0mark 10000000*2 iterations 20 paralell... result 12238010084437174696
65.569750 milliseconds 400000000 additions 6.100374 gigainops

f1b0mark 10000000*2 iterations 21 paralell... result 7315887366546167946
73.230417 milliseconds 420000000 additions 5.735322 gigainops

f1b0mark 10000000*2 iterations 22 paralell... result 2393764648655161196
92.353417 milliseconds 440000000 additions 4.764307 gigainops

f1b0mark 10000000*2 iterations 23 paralell... result 15918386004473706062
92.848834 milliseconds 460000000 additions 4.954289 gigainops

f1b0mark 10000000*2 iterations 24 paralell... result 10996263286582699312
92.442667 milliseconds 480000000 additions 5.192408 gigainops

f1b0mark 10000000*2 iterations 25 paralell... result 6074140568691692562
105.902500 milliseconds 500000000 additions 4.721324 gigainops

f1b0mark 10000000*2 iterations 26 paralell... result 1152017850800685812
88.753916 milliseconds 520000000 additions 5.858896 gigainops

f1b0mark 10000000*2 iterations 27 paralell... result 14676639206619230678
91.677458 milliseconds 540000000 additions 5.890216 gigainops

f1b0mark 10000000*2 iterations 28 paralell... result 9754516488728223928
92.091333 milliseconds 560000000 additions 6.080920 gigainops

f1b0mark 10000000*2 iterations 29 paralell... result 4832393770837217178
95.060708 milliseconds 580000000 additions 6.101364 gigainops

f1b0mark 10000000*2 iterations 30 paralell... result 18357015126655762044
103.767250 milliseconds 600000000 additions 5.782171 gigainops

f1b0mark 10000000*2 iterations 31 paralell... result 13434892408764755294
104.614792 milliseconds 620000000 additions 5.926504 gigainops

f1b0mark 10000000*2 iterations 32 paralell... result 8512769690873748544
111.874417 milliseconds 640000000 additions 5.720700 gigainops

 
The following users thanked this post: bd139, magic

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6427
  • Country: nz
Re: Apples new M1 microprocessor
« Reply #269 on: November 30, 2020, 02:48:16 pm »
Rosetta results are insane. The program actually runs slightly more quickly than native at 4.1 seconds overall vs 4.45 seconds, but the program-internal timings are crazy.

Assuming that the clock_gettime() calls do actually work properly, the only explanation that seems to make sense is if Rosetta is compiling each function just in time (which takes a while) but is optimizing the basic blocks. The result values are the same.

==================== 64bit ====================
f1b0mark 10000000*2 iterations 1 paralell... result 13524621355818544866
0.152508 milliseconds 20000000 additions 131.140661 gigainops

f1b0mark 10000000*2 iterations 2 paralell... result 8602498637927538116
0.150378 milliseconds 40000000 additions 265.996356 gigainops

f1b0mark 10000000*2 iterations 3 paralell... result 3680375920036531366
0.168184 milliseconds 60000000 additions 356.752129 gigainops

f1b0mark 10000000*2 iterations 4 paralell... result 17204997275855076232
0.175210 milliseconds 80000000 additions 456.594943 gigainops

f1b0mark 10000000*2 iterations 5 paralell... result 12282874557964069482
0.192716 milliseconds 100000000 additions 518.898275 gigainops

f1b0mark 10000000*2 iterations 6 paralell... result 7360751840073062732
0.198756 milliseconds 120000000 additions 603.755358 gigainops

f1b0mark 10000000*2 iterations 7 paralell... result 2438629122182055982
0.485385 milliseconds 140000000 additions 288.430833 gigainops

f1b0mark 10000000*2 iterations 8 paralell... result 15963250478000600848
0.993580 milliseconds 160000000 additions 161.033837 gigainops

f1b0mark 10000000*2 iterations 9 paralell... result 11041127760109594098
0.856754 milliseconds 180000000 additions 210.095313 gigainops

f1b0mark 10000000*2 iterations 10 paralell... result 6119005042218587348
1.048722 milliseconds 200000000 additions 190.708310 gigainops

f1b0mark 10000000*2 iterations 11 paralell... result 1196882324327580598
1.126819 milliseconds 220000000 additions 195.239874 gigainops

f1b0mark 10000000*2 iterations 12 paralell... result 14721503680146125464
1.205832 milliseconds 240000000 additions 199.032701 gigainops

f1b0mark 10000000*2 iterations 13 paralell... result 9799380962255118714
1.190788 milliseconds 260000000 additions 218.342812 gigainops

f1b0mark 10000000*2 iterations 14 paralell... result 4877258244364111964
1.413808 milliseconds 280000000 additions 198.046694 gigainops

f1b0mark 10000000*2 iterations 15 paralell... result 18401879600182656830
1.527521 milliseconds 300000000 additions 196.396645 gigainops

f1b0mark 10000000*2 iterations 16 paralell... result 13479756882291650080
1.671119 milliseconds 320000000 additions 191.488458 gigainops

f1b0mark 10000000*2 iterations 17 paralell... result 8557634164400643330
1.832372 milliseconds 340000000 additions 185.551842 gigainops

f1b0mark 10000000*2 iterations 18 paralell... result 3635511446509636580
1.981824 milliseconds 360000000 additions 181.650843 gigainops

f1b0mark 10000000*2 iterations 19 paralell... result 17160132802328181446
2.217315 milliseconds 380000000 additions 171.378446 gigainops

f1b0mark 10000000*2 iterations 20 paralell... result 12238010084437174696
2.748137 milliseconds 400000000 additions 145.553151 gigainops

f1b0mark 10000000*2 iterations 21 paralell... result 7315887366546167946
2.935518 milliseconds 420000000 additions 143.075260 gigainops

f1b0mark 10000000*2 iterations 22 paralell... result 2393764648655161196
3.353458 milliseconds 440000000 additions 131.207846 gigainops

f1b0mark 10000000*2 iterations 23 paralell... result 15918386004473706062
2.991130 milliseconds 460000000 additions 153.788033 gigainops

f1b0mark 10000000*2 iterations 24 paralell... result 10996263286582699312
1.105848 milliseconds 480000000 additions 434.056037 gigainops

f1b0mark 10000000*2 iterations 25 paralell... result 6074140568691692562
1.373220 milliseconds 500000000 additions 364.107718 gigainops

f1b0mark 10000000*2 iterations 26 paralell... result 1152017850800685812
1.190110 milliseconds 520000000 additions 436.934401 gigainops

f1b0mark 10000000*2 iterations 27 paralell... result 14676639206619230678
1.425837 milliseconds 540000000 additions 378.724917 gigainops

f1b0mark 10000000*2 iterations 28 paralell... result 9754516488728223928
1.303101 milliseconds 560000000 additions 429.744126 gigainops

f1b0mark 10000000*2 iterations 29 paralell... result 4832393770837217178
1.649733 milliseconds 580000000 additions 351.572042 gigainops

f1b0mark 10000000*2 iterations 30 paralell... result 18357015126655762044
1.443503 milliseconds 600000000 additions 415.655527 gigainops

f1b0mark 10000000*2 iterations 31 paralell... result 13434892408764755294
1.630618 milliseconds 620000000 additions 380.223940 gigainops

f1b0mark 10000000*2 iterations 32 paralell... result 8512769690873748544
1.588216 milliseconds 640000000 additions 402.967858 gigainops
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 8060
  • Country: pl
Re: Apples new M1 microprocessor
« Reply #270 on: November 30, 2020, 03:32:39 pm »
10x speedup with Rosetta, haha, no way it's real ;D
Something is not right with clocking or maybe it optimizes things away because it's not constrained by my bogus volatile annotations. A sufficiently smart compiler could reduce this whole benchmark to a single run with N=1 and then easily deduce all other results.

Code: [Select]
==================== 64bit ====================
f1b0mark 10000000*2 iterations 1 paralell... result 13524621355818544866
6.493208 milliseconds 20000000 additions 3.080142 gigainops

f1b0mark 10000000*2 iterations 2 paralell... result 8602498637927538116
6.491041 milliseconds 40000000 additions 6.162340 gigainops

f1b0mark 10000000*2 iterations 3 paralell... result 3680375920036531366
6.990208 milliseconds 60000000 additions 8.583436 gigainops

f1b0mark 10000000*2 iterations 4 paralell... result 17204997275855076232
7.247458 milliseconds 80000000 additions 11.038353 gigainops

f1b0mark 10000000*2 iterations 5 paralell... result 12282874557964069482
7.923459 milliseconds 100000000 additions 12.620751 gigainops

f1b0mark 10000000*2 iterations 6 paralell... result 7360751840073062732
8.440000 milliseconds 120000000 additions 14.218009 gigainops

f1b0mark 10000000*2 iterations 7 paralell... result 2438629122182055982
9.547209 milliseconds 140000000 additions 14.663971 gigainops

f1b0mark 10000000*2 iterations 8 paralell... result 15963250478000600848
8.864500 milliseconds 160000000 additions 18.049523 gigainops

f1b0mark 10000000*2 iterations 9 paralell... result 11041127760109594098
10.047375 milliseconds 180000000 additions 17.915127 gigainops

f1b0mark 10000000*2 iterations 10 paralell... result 6119005042218587348
11.037625 milliseconds 200000000 additions 18.119840 gigainops

f1b0mark 10000000*2 iterations 11 paralell... result 1196882324327580598
12.031625 milliseconds 220000000 additions 18.285144 gigainops

f1b0mark 10000000*2 iterations 12 paralell... result 14721503680146125464
13.026417 milliseconds 240000000 additions 18.424099 gigainops

f1b0mark 10000000*2 iterations 13 paralell... result 9799380962255118714
14.066792 milliseconds 260000000 additions 18.483248 gigainops

f1b0mark 10000000*2 iterations 14 paralell... result 4877258244364111964
15.126333 milliseconds 280000000 additions 18.510765 gigainops

f1b0mark 10000000*2 iterations 15 paralell... result 18401879600182656830
36.436875 milliseconds 300000000 additions 8.233417 gigainops
This is more plausible and a very good result. Assuming 3.2GHz clock, this chip manages 6 additions per cycle most of the time. That's twice the throughput of previous decade's TOTL x86.

Yes, it collapses after N=14 because it runs out of registers and starts to spill. Ditto with Amd64 after N=7 and x86 after N=3. Reportedly, some recent Zens feature a very fast store to load forwarding which should improve performance here, up to another limit.

I have no explanation for the slow ramp-up. The first line clearly shows that additions have 1 cycle latency so more additions in parallel should just scale linearly until all ALUs are saturated.

Maybe LLVM didn't unroll enough. Please try with this Makefile, it adds some command line options which significantly improve unrolling on old GCC - now it gets close to theoretical limits on x86 and Cortex A15. LLVM is supposed to be command-line compatible, so maybe it will help too.

I also refactored the code a bit, so a new version is attached too. It is now trivial to run one individual benchmark configuration from main for testing with tools like perf. Silly file extensions because of forum engine restrictions ::)
« Last Edit: November 30, 2020, 03:38:32 pm by magic »
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 6427
  • Country: nz
Re: Apples new M1 microprocessor
« Reply #271 on: December 01, 2020, 12:53:16 am »
10x speedup with Rosetta, haha, no way it's real ;D
Something is not right with clocking or maybe it optimizes things away because it's not constrained by my bogus volatile annotations. A sufficiently smart compiler could reduce this whole benchmark to a single run with N=1 and then easily deduce all other results.

volatile means nothing in machine language. It's entirely within its rights to optimize 100 adds in straight-line unrolled code to a "multiply by 100 and add" -- which is three "shift and add" instructions on arm64.

The rosetta version *did* run 10% faster than the native version (wall clock time), even including translation overhead, and got the same printed results. There's no arguing against that.
 
The following users thanked this post: tooki, DiTBho

Offline magic

  • Super Contributor
  • ***
  • Posts: 8060
  • Country: pl
Re: Apples new M1 microprocessor
« Reply #272 on: December 01, 2020, 07:13:47 am »
The cheating precluded by volatile is to realize that the critical function is always called with {1,1,...} as its argument and cache the output between program executions. I think this wouldn't be entirely out of the realm of possibilities as far as JITs go, but if you say the program still takes 90% of native run time and only the internal timing reports are wrong, then :-//

I think all other code transformations that Rosetta could perform would also be available to Apple's C++ compiler, so it's not clear how Rosetta could be faster. Here's two that come to my mind:
1. add all x[N] numbers together and run only one series of Fibonacci iterations on their sum - it's all linear, after all (I think?)
2. replace the 10 million iterations of addition with an equivalent logarithmic time matrix multiplication loop

Both appear to be outside the reach of GCC/LLVM for now :phew: and I anticipate that either would result in an order of magnitude difference, so that's not what happens. I suspect something boring like unrolling differences between your Aarch64 and Amd64 compilers.

You can't replace those additions with multiplications, easily.

edit
Okay, there is one "dumb" optimization which doesn't require any knowledge of maths: tiling the inner loops for data locality. It would almost eliminate memory accesses and maintain full GIGAINOPS throughput of the CPU into arbitrary numbers of parallel sequences.

High end scientific compilers could pull it off. I would be surprised if Rosetta has this capability, and even more so if it does but Apple's compiler does not. And it's still more difference in total run time than 10%...
« Last Edit: December 01, 2020, 07:59:52 am by magic »
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 9180
  • Country: de
  • A qualified hobbyist ;)
Re: Apples new M1 microprocessor
« Reply #273 on: December 01, 2020, 03:38:08 pm »
The volatile memory type declaration simply tells the C compiler that the variable can change any time, e.g. by an interrupt handler. So the compiler doesn't optimize the variable usage by keeping it in some register and fetches/stores the current value each time when accessed.
 
The following users thanked this post: DiTBho

Offline Cerebus

  • Super Contributor
  • ***
  • Posts: 10576
  • Country: gb
Re: Apples new M1 microprocessor
« Reply #274 on: December 01, 2020, 05:14:59 pm »
The volatile memory type declaration simply tells the C compiler that the variable can change any time, e.g. by an interrupt handler. So the compiler doesn't optimize the variable usage by keeping it in some register and fetches/stores the current value each time when accessed.

The important bit there is the preservation of the reads and writes to storage, producing the same externally visible series of storage events rather than merely producing the same values in storage at the end.

Just for fun I thought that I'd see what LLVM does in the presence of volatile at different optimisation levels. I stuck with the Intel version in the expectation that more folks can read Intel assembler than can read ARM assembler. I did actually run the same with -arch arm and the optimisations are, unsurprisingly, exactly the same logically speaking. The only significant difference with the ARM code is that there are many more loads and stores, which you'd expect from a risc architecture versus a cisc architecture with 'add to memory' instructions.

First up, the C code. Nothing clever, just two fixed length loops incrementing global variables one of which is labelled volatile, one which is not:


int bert;

void fred()
{
    for (int i = 0; i < 10; i++)
    {
        bert++;
    }
}

volatile int harry;

void charlie()
{
    for (int i = 0; i < 10; i++)
    {
        harry++;
    }
}



I've removed all the cruft, procedure preludes and postludes and the like from the assembly code to make it more legible.

First up, no optimisation. As you can see, both procedures are compiled into identical code:



_fred:                                  ## @fred
   movl   $0, -4(%rbp)
LBB0_1:                                 ## =>This Inner Loop Header: Depth=1
   cmpl   $10, -4(%rbp)
   jge   LBB0_4
## %bb.2:                               ##   in Loop: Header=BB0_1 Depth=1
   movq   _bert@GOTPCREL(%rip), %rax
   movl   (%rax), %ecx
   addl   $1, %ecx
   movl   %ecx, (%rax)
## %bb.3:                               ##   in Loop: Header=BB0_1 Depth=1
   movl   -4(%rbp), %eax
   addl   $1, %eax
   movl   %eax, -4(%rbp)
   jmp   LBB0_1
   retq

_charlie:                               ## @charlie
   movl   $0, -4(%rbp)
LBB1_1:                                 ## =>This Inner Loop Header: Depth=1
   cmpl   $10, -4(%rbp)
   jge   LBB1_4
## %bb.2:                               ##   in Loop: Header=BB1_1 Depth=1
   movq   _harry@GOTPCREL(%rip), %rax
   movl   (%rax), %ecx
   addl   $1, %ecx
   movl   %ecx, (%rax)
## %bb.3:                               ##   in Loop: Header=BB1_1 Depth=1
   movl   -4(%rbp), %eax
   addl   $1, %eax
   movl   %eax, -4(%rbp)
   jmp   LBB1_1
   retq



Now with -O1. For the non-volatile version it's optimised the loop away entirely and replaced the multiple additions by a single constant addition of 10. For the volatile it's optimised the loop induction variable but kept individual additions to the volatile variable.



_fred:                                  ## @fred
   movq   _bert@GOTPCREL(%rip), %rax
   addl   $10, (%rax)
   retq

_charlie:                               ## @charlie
   movl   $10, %eax
   movq   _harry@GOTPCREL(%rip), %rcx
LBB1_1:                                 ## =>This Inner Loop Header: Depth=1
   incl   (%rcx)
   decl   %eax
   jne   LBB1_1
   retq





Now with -O2. For the non-volatile version it produces identical code, not surprising as the -O1 optimisation is, quite literally, as close to optimal as you can get without global optimization (where hopefully the compiler would work out that this loop produces a value that is never used anywhere else and elide all of this). The volatile version has had the loop unrolled, but is still producing the same set of externally visible actions as the previous two versions.



_fred:                                  ## @fred
   movq   _bert@GOTPCREL(%rip), %rax
   addl   $10, (%rax)
   retq
                                        ## -- End function
_charlie:                               ## @charlie
   movq   _harry@GOTPCREL(%rip), %rax
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   incl   (%rax)
   retq




Using -O3 produces exactly the same code as -O2, so there's nothing new to show. So does -Ofast. -Os and -Oz produce the same code as -O1

Anybody got a syringe I can use to squeeze the magic smoke back into this?
 
The following users thanked this post: bd139


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf