# Julia 1.7 on M1 is Incredible?

**URL:** https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498
**Category:** Performance
**Created:** [December 22, 2021, 3:43pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498 "2021-12-22T15:43:21Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)
#### Post date: [December 22, 2021, 3:43pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498/1 "2021-12-22T15:43:21Z")

</div>

I recently spent a day fixing performance bottlenecks from my group’s research code (not important I think but I’m referring to [ACE.jl](https://github.com/ACEsuit/ACE.jl)). I had some unexpected experiences and am hoping somebody will help me understand? I work on Julia 1.7 on my M1 MacBook pro. After I was done optimizing I then tested also on Julia 1.6 on the M1, and on both 1.6 and 1.7 on an EPYC 7702 workstation.

The basic take-away: Julia 1.7 optimizes much better than 1.6 (my codes anyhow), and Julia 1.7 optimizes MUCH MUCH better on the M1 than on the EPYC. (what?!?)

1. **Small Surprise:** 1.6 added an allocation close to some hot loops and the performance dropped by several factors. Nice that Julia keeps getting more and more clever about optimizing, I thought. But I was a bit surprised about this particular piece of code (see below).
2. **Big Surprise:** On the EPYC workstation the results were similar for **BOTH** 1.6 and 1.7 as they were for 1.6 on the M1. That is, on 1.7, I had the same allocation problem as on 1.6. This only occurred on the EPYC but not on the M1. _I have no explanation for this whatsoever?_
3. **Medium Surprise:** I fixed the allocations (again, see below) on all systems and Julia versions. Even now, the code on the M1 runs about a factor 3 faster than on the EPYC. Moreover, Julia 1.7 code runs about a 10-20% faster on both systems (nice!).

The last point is actually of practical importance and not just curiosity. Where do I need to start to fix the performance on the EPYC? Clock speeds are roughly the same, so is it the increases memory bandwidth of the M1 (almost double)? Cache? Something entirely different?

## A little more detail:

The specific piece of code that the points above are referring to goes something like this (it is a little simplified, but I think the gist is right): this returns a thread-safe pre-allocated temporary array (if available on a stack inside `basis.pool`) and otherwise allocates one; the intention is that one almost always reuses the pre-allocated arrays, but to have a fall-back for faster development or testing when needed.

```Julia
acquire!(basis, T) = hasproperty(basis, :pool) ? acquire!(basis.pool, T) : zeros(T, length(basis))
release!(basis, A) = hasproperty(basis, :pool) ? release!(basis.pool, A) : nothing.

```

On all systems except 1.7 on M1, in order for my code to not allocate, I had to replace these functions with `@generated` functions that “manually” resolved the `if hasproperty(basis, :pool) ...` . The _actual_ code is here just in case: [[code]](https://github.com/ACEsuit/ACEbase.jl/blob/3127b688f41cdd14247f8db5c8e4f531e31dc761/src/ACEbase.jl#L122), [[tests]](https://github.com/ACEsuit/ACE.jl/blob/main/profile/profile_basis_tests.jl).

```julia-auto
Julia Version 1.7.0
Commit 3bf9d17731 (2021-11-30 12:12 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin21.1.0)
  CPU: Apple M1 Max
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, cyclone)

Julia Version 1.7.0
Commit 3bf9d17731 (2021-11-30 12:12 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: AMD EPYC-Rome Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, znver2)

```

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [December 22, 2021, 3:46pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498/2 "2021-12-22T15:46:27Z")

</div>

@Elrod mentioned that it might be the cache sizes. We saw M1 dominating PDE benchmarks.

[https://github.com/SciML/MethodOfLines.jl/issues/2#issuecomment-862807968](https://github.com/SciML/MethodOfLines.jl/issues/2#issuecomment-862807968)

---

<div class="post-metadata">

### Author: ![pazzo83](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pazzo83/32/232_2.png) [@pazzo83](https://discourse.julialang.org/u/pazzo83)
#### Post date: [December 22, 2021, 4:00pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498/3 "2021-12-22T16:00:23Z")

</div>

Yeah, 1.7 on my M1 has been awesome. Pretty much the only issue (and why I still use the x86 version of 1.6.\* occasionally) is some issues with multithreading, but it looks like that is being addressed in 1.7.1.

---

<div class="post-metadata">

### Author: ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)
#### Post date: [December 23, 2021, 3:50pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498/4 "2021-12-23T15:50:03Z")

</div>

You are not the first to notice

> [@JuMP.jl and DifferentialEquation.jl benchmarks on M1 Max Julia 1.7.0 x89 vs ARM. (spoiler: ARM is 1.5-2x faster)](https://discourse.julialang.org/t/jump-jl-and-differentialequation-jl-benchmarks-on-m1-max-julia-1-7-0-x89-vs-arm-spoiler-arm-is-1-5-2x-faster/72496):
>
> This is just FYI for fun in case people are interested. I compared JuMP, DiffEq and simple sort() on M1 Max MacBook using official binaries of Julia 1.7.0 with either Native ARM or x86 with Rosetta2. Native ARM version seems to be 1.5-2x faster in JuMP, DiffEq and sort() benchmarks. ARM Julia 1.7 still has a bunch of bugs ([https://github.com/JuliaLang/julia/issues/41440](https://github.com/JuliaLang/julia/issues/41440) and [https://github.com/JuliaLang/julia/issues/41820](https://github.com/JuliaLang/julia/issues/41820)) and even the processor seems to not be recognized correctly ([Feature/CP…](https://github.com/JuliaLang/julia/issues/40876)

It even prompted me to look up the price of a new Macbook. I think I can wait 2x as long for my results 🙂

---

<div class="post-metadata">

### Author: ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)
#### Post date: [December 23, 2021, 4:45pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498/5 "2021-12-23T16:45:57Z")

</div>

Thanks for this link and the comments.

Still - my main surprise and puzzle is that J17 appears to produce different code in the M1 than in the EPYC, with fewer allocations (possibly due to improved constant propagation, but I’m not certain if this).

A different LLVM? Or does the compiler decide at random how much effort to put into optimising the code?

---

<div class="post-metadata">

### Author: ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)
#### Post date: [December 29, 2021, 10:26pm UTC](https://discourse.julialang.org/t/julia-1-7-on-m1-is-incredible/73498/6 "2021-12-29T22:26:05Z")

</div>

I have the 2020 MacBook with the original M1 chip and 1.7.1 is 30% – 50% faster than the 2019 8 core Intel IMac I have in my office. This is with openblas on the M1 and MKL on the Intel.

Eagerly awaiting a vendor blas for apple chips.
