bytedance / gopkg

Universal Utilities for Go
Apache License 2.0
1.71k stars 224 forks source link

feat(lscq): add arm64 support #152

Closed kabu1204 closed 2 years ago

kabu1204 commented 2 years ago

Using CASP instruction to implement double-width CAS for arm64. The CASP instruction is available for instruction set Armv8.1+ (inclusive, Apple M1/M2/A12, Snapdragon 845, etc). All tests in lscq_test.go passed on Macbook Air M1 2020, macOS 12.5.1.

Change-Id: Ieb89fa9361f1fce8fb52b102dca556867f7e8e8a

kabu1204 commented 2 years ago

Update: use cpu.ARM64.HasATOMICS to determine whether the arm64 cpu has standalone CAS instructions(CASP is only available for ARMv8.1+, use LDAX/STLX instruction on ARMv8.0 instead).

kabu1204 commented 2 years ago

Update: detect arm64HasAtomics correctly on darwin

Before: arm64HasAtomics = golang.org/x/sys/cpu.ARM64.HasATOMICS. This is correct on other platforms except darwin_arm64. After checking the src, I found that the package golang.org/x/sys/cpu simply does not support darwin_arm64 :), so it sets all optional cpu features of arm64 to false on darwin. This would not affect the correctness of LSCQ on darwin_arm64, the Cas128bit will just take the slightly slower way(using LDAXP/STLXP instruction).

After: Use sysctlEnabled() to detect cpu features on darwin_arm64. The function is exported from internal/cpu by go:linkname. It uses sysctlbyname, a system call provided by darwin, to detect whether the given cpu features is enabled. On other platforms, we still use golang.org/x/sys/cpu.ARM64.HasATOMICS. Therefore, we can now use faster CASPD instruction on darwin_arm64.

All test and bench passed on darwin(m1) and ubuntu20.04(ampere altra).

More details are written in the commit message.

zhangyunhao116 commented 2 years ago

Nice work! It works fine in my liunx/arm64 and darwin/arm64 environments. Thanks!

zhangyunhao116 commented 2 years ago

@kabu1204 It's fine, the test is passed on my linux/amd64 machine, since it is not a feature for linux/amd64, I think it's ok to merge this. Thanks again!