[Rd] R 4.5.3 macOS arm64: severe matrix-product performance regression vs R 4.5.2 due to libRblas.dylib selecting libRblas.0.dylib instead of libRblas.vecLib.dylib

Simon Urbanek @|mon@urb@nek @end|ng |rom R-project@org
Fri Mar 27 02:52:20 CET 2026


Jeffrey,

the choice of BLAS is up to the user (See R for Mac FAQ 10.5 [1]), both are always available so it's your call to pick the one which works for you.

Historically, we set the default reference BLAS for its stability, but in R 4.5.2 there was an attempt to enable the accelerated BLAS on arm64, because the performance difference can be up to 100x speed up on Apple Silicon hardware due to the fact that Accelerate can use the "secret" Apple matrix co-processor (AMX) for BLAS operations. Unfortunately, Accelerate is not fork-safe so it can break[2] when used with paralellization in R, so we have reverted back the default to the reference BLAS in R 4.5.3 as that one is guaranteed to work. If you know that the code you use is safe, you can switch to the accelerated BLAS.

Cheers,
Simon


[1] - https://cran.r-project.org/bin/macosx/RMacOSX-FAQ.html#Which-BLAS-is-used-and-how-can-it-be-changed_003f
[2] - https://stat.ethz.ch/pipermail/r-sig-mac/2026-January/015322.html



> On 27 Mar 2026, at 12:48, Jeffrey Racine <racinejs using gmail.com> wrote:
> 
> Greetings,
> 
> I am reporting a substantial performance regression on macOS arm64 when
> moving from `R 4.5.2` to `R 4.5.3`.
> 
> This first appeared while benchmarking the `np` package, where a
> conditional-density least-squares cross-validation route (`npcdensbw(...,
> bwmethod="cv.ls")`) became roughly 5x slower under `R 4.5.3`. After
> investigation, the package itself appears not to be at fault: the
> regression can be reproduced directly with base matrix-product operations
> and seems to be caused by a change in which BLAS library `R 4.5.3` uses on
> macOS arm64.
> 
> ### System
> 
> - Hardware: Apple Silicon (`aarch64`)
> - OS: macOS Tahoe 26.4
> - `R 4.5.2`: `R version 4.5.2 (2025-10-31)`
> - `R 4.5.3`: `R version 4.5.3 (2026-03-11)`
> 
> ### Summary of findings
> 
> Using the official macOS arm64 installers:
> 
> - `R-4.5.2-arm64.pkg`
> - `R-4.5.3-arm64.pkg`
> 
> I unpacked both installers and compared their framework payloads.
> 
> Key visible result:
> 
> - In `R 4.5.2`, `Resources/lib/libRblas.dylib` points to
> `libRblas.vecLib.dylib`
> - In `R 4.5.3`, `Resources/lib/libRblas.dylib` points to `libRblas.0.dylib`
> 
> Both payloads still contain both files:
> 
> - `libRblas.0.dylib`
> - `libRblas.vecLib.dylib`
> 
> ### Payload evidence
> 
> `R 4.5.2` unpacked payload:
> 
> ```text
> lrwxr-xr-x ... libRblas.dylib -> libRblas.vecLib.dylib
> -rwxr-xr-x ... libRblas.0.dylib
> -rwxr-xr-x ... libRblas.vecLib.dylib
> ```
> 
> `R 4.5.3` unpacked payload:
> 
> ```text
> lrwxr-xr-x ... libRblas.dylib -> libRblas.0.dylib
> -rwxr-xr-x ... libRblas.0.dylib
> -rwxr-xr-x ... libRblas.vecLib.dylib
> ```
> 
> Additional payload comparison:
> 
> - `Makeconf`, `ldpaths`, `Renviron`, `bin/R`, and installer scripts were
> byte-identical between `4.5.2` and `4.5.3`
> - the executable `__text` sections of `libRblas.0.dylib` and
> `libRlapack.dylib` were identical
> - the executable `__text` section of `libR.dylib` differed
> 
> ### How the runtimes were tested
> 
> I ran both R versions directly from the unpacked installer payloads using
> `Resources/bin/exec/R`, with `R_HOME` and `DYLD_LIBRARY_PATH` pointed at
> each unpacked framework. This avoids relying on the live installed system
> framework.
> 
> Example invocation:
> 
> ```bash
> R_HOME=/tmp/R452_pkg/R-fw.pkg/Payload/R.framework/Versions/4.5-arm64/Resources
> \
> DYLD_LIBRARY_PATH=/tmp/R452_pkg/R-fw.pkg/Payload/R.framework/Versions/4.5-arm64/Resources/lib
> \
> /tmp/R452_pkg/R-fw.pkg/Payload/R.framework/Versions/4.5-arm64/Resources/bin/exec/R
> --vanilla -q -f /tmp/r_blas_probe2.R
> ```
> 
> and similarly for `R 4.5.3`.
> 
> ### Minimal reproducer
> 
> ```r
> set.seed(1)
> n <- 1000000L
> x <- rnorm(n)
> y <- rnorm(n)
> A <- matrix(rnorm(2000L*2000L), 2000L, 2000L)
> B <- matrix(rnorm(2000L*2000L), 2000L, 2000L)
> 
> cat(R.version.string, "\n")
> cat("crossprod vec\n")
> print(system.time(for(i in 1:40) z <- crossprod(x, y)))
> cat("matmult\n")
> print(system.time(C <- A %*% B))
> ```
> 
> ### Observed timings
> 
> `R 4.5.2`:
> 
> - `crossprod()` elapsed about `0.032s`
> - `%*%` elapsed about `0.034s`
> 
> Observed output:
> 
> ```text
> R version 4.5.2 (2025-10-31)
> crossprod vec
> user system elapsed
> 0.031 0.002 0.032
> matmult
> user system elapsed
> 0.058 0.003 0.034
> ```
> 
> `R 4.5.3`:
> 
> - `crossprod()` elapsed about `0.072s`
> - `%*%` elapsed about `2.443s`
> 
> Observed output:
> 
> ```text
> R version 4.5.3 (2026-03-11)
> crossprod vec
> user system elapsed
> 0.071 0.000 0.072
> matmult
> user system elapsed
> 2.381 0.057 2.443
> ```
> 
> This is a very large regression for `%*%` and a clear regression for
> `crossprod()`.
> 
> ### Loaded libraries during runtime
> 
> For the unpacked `R 4.5.2` process, `lsof` showed:
> 
> ```text
> ... /tmp/R452_pkg/.../Resources/lib/libRblas.vecLib.dylib
> ... /tmp/R452_pkg/.../Resources/lib/libR.dylib
> ... /tmp/R452_pkg/.../Resources/lib/libRlapack.dylib
> ```
> 
> `vmmap` also showed that Apple Accelerate / vecLib libraries were mapped.
> 
> For the unpacked `R 4.5.3` process, `lsof` showed:
> 
> ```text
> ... /tmp/R453_pkg/.../Resources/lib/libRblas.0.dylib
> ... /tmp/R453_pkg/.../Resources/lib/libR.dylib
> ... /tmp/R453_pkg/.../Resources/lib/libRlapack.dylib
> ```
> 
> ### Critical confirmation
> 
> In a temporary copy of the unpacked `R 4.5.3` framework, I changed only
> this symlink:
> 
> - from:
> 
> ```text
> libRblas.dylib -> libRblas.0.dylib
> ```
> 
> - to:
> 
> ```text
> libRblas.dylib -> libRblas.vecLib.dylib
> ```
> 
> After that single change, the `R 4.5.3` runtime regained the fast timings:
> 
> ```text
> R version 4.5.3 (2026-03-11)
> crossprod vec
> user system elapsed
> 0.032 0.002 0.033
> matmult
> user system elapsed
> 0.055 0.003 0.032
> ```
> 
> `lsof` then showed:
> 
> ```text
> ... /tmp/R453_test/.../Resources/lib/libRblas.vecLib.dylib
> ... /tmp/R453_test/.../Resources/lib/libR.dylib
> ... /tmp/R453_test/.../Resources/lib/libRlapack.dylib
> ```
> 
> So the regression appears to be directly tied to the BLAS target selected
> by `libRblas.dylib` in the macOS arm64 `R 4.5.3` distribution.
> 
> ### Why this matters
> 
> This caused a large apparent regression in package benchmarks, but the
> package code was not the source. The underlying issue is visible in base
> matrix-product operations.
> 
> For performance-sensitive code relying on repeated dot products or matrix
> multiplies, the effect is substantial.
> 
> One affected package-level example was `np::npcdensbw(..., bwmethod =
> "cv.ls")`,
> whose hot path repeatedly uses BLAS-backed dot products inside
> conditional-density CVLS block computations.
> 
> ### Expected behavior
> 
> I would expect `R 4.5.3` on macOS arm64 not to regress dramatically
> relative to `R 4.5.2` for basic matrix products on the same hardware.
> 
> At minimum, if the BLAS target changed intentionally, I would expect that
> change not to impose such a severe runtime penalty.
> 
> ### Request
> 
> Could you please confirm whether the `libRblas.dylib -> libRblas.0.dylib`
> change in the macOS arm64 `R 4.5.3` installer was intentional?
> 
> If intentional, is there a recommended way to restore the previous fast
> vecLib-backed behavior?
> 
> If not intentional, this appears to be a macOS arm64 packaging/runtime
> regression in `R 4.5.3`.
> 
> I can provide exact command transcripts and additional package-level
> evidence if helpful.
> 
> ## Local investigation notes
> 
> This report was motivated by a package-level timing cliff in `np`, but the
> package code appears exonerated:
> 
> - the relevant `np` hot path remains unchanged in current source
> - the same slowdown occurs across different `np` source snapshots when run
> under `R 4.5.3`
> - the same `np` source and same compiled package are fast again under `R
> 4.5.2`
> 
> The key practical interpretation is:
> 
> - not a package source regression
> - likely an R macOS BLAS-linkage/runtime regression in `4.5.3`
> 
> ## Relevant local files
> 
> - [R-4.5.2-arm64.pkg](/Users/jracine/Development/R-4.5.2-arm64.pkg)
> - [R-4.5.3-arm64.pkg](/Users/jracine/Development/R-4.5.3-arm64.pkg)
> 
> [[alternative HTML version deleted]]
> 
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 



More information about the R-devel mailing list