From e4b03f9425a70f53acb9526dc9cd9c21373308e5 Mon Sep 17 00:00:00 2001 From: fanzha02 Date: Thu, 20 Apr 2023 07:28:50 +0000 Subject: [PATCH] internal/cpu: add a detection for Neoverse(N2, V2) cores The memmove implementation relies on the variable runtime.arm64UseAlignedLoads to select fastest code path. Considering Neoverse N2 and V2 cores prefer aligned loads, this patch adds code to detect them for memmove performance. And this patch uses a new variable ARM64.IsNeoverse to represent all Neoverse cores, removing the more specific versions. Change-Id: I9e06eae01a0325a0b604ac6af1e55711dd6133f7 Reviewed-on: https://go-review.googlesource.com/c/go/+/487815 Reviewed-by: Joel Sing Reviewed-by: Dmitri Shuralyov Run-TryBot: Fannie Zhang Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot --- src/internal/cpu/cpu.go | 23 +++++++++++------------ src/internal/cpu/cpu_arm64.go | 3 +-- src/internal/cpu/cpu_arm64_hwcap.go | 20 +++++++++++--------- src/runtime/cpuflags_arm64.go | 2 +- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/internal/cpu/cpu.go b/src/internal/cpu/cpu.go index aef9fb3be7..1352810f42 100644 --- a/src/internal/cpu/cpu.go +++ b/src/internal/cpu/cpu.go @@ -57,18 +57,17 @@ var ARM struct { // The booleans in ARM64 contain the correspondingly named cpu feature bit. // The struct is padded to avoid false sharing. var ARM64 struct { - _ CacheLinePad - HasAES bool - HasPMULL bool - HasSHA1 bool - HasSHA2 bool - HasSHA512 bool - HasCRC32 bool - HasATOMICS bool - HasCPUID bool - IsNeoverseN1 bool - IsNeoverseV1 bool - _ CacheLinePad + _ CacheLinePad + HasAES bool + HasPMULL bool + HasSHA1 bool + HasSHA2 bool + HasSHA512 bool + HasCRC32 bool + HasATOMICS bool + HasCPUID bool + IsNeoverse bool + _ CacheLinePad } var MIPS64X struct { diff --git a/src/internal/cpu/cpu_arm64.go b/src/internal/cpu/cpu_arm64.go index 85210aa00c..4a302f27d5 100644 --- a/src/internal/cpu/cpu_arm64.go +++ b/src/internal/cpu/cpu_arm64.go @@ -19,8 +19,7 @@ func doinit() { {Name: "crc32", Feature: &ARM64.HasCRC32}, {Name: "atomics", Feature: &ARM64.HasATOMICS}, {Name: "cpuid", Feature: &ARM64.HasCPUID}, - {Name: "isNeoverseN1", Feature: &ARM64.IsNeoverseN1}, - {Name: "isNeoverseV1", Feature: &ARM64.IsNeoverseV1}, + {Name: "isNeoverse", Feature: &ARM64.IsNeoverse}, } // arm64 uses different ways to detect CPU features at runtime depending on the operating system. diff --git a/src/internal/cpu/cpu_arm64_hwcap.go b/src/internal/cpu/cpu_arm64_hwcap.go index 88cb8b9064..2fabbb6edc 100644 --- a/src/internal/cpu/cpu_arm64_hwcap.go +++ b/src/internal/cpu/cpu_arm64_hwcap.go @@ -39,22 +39,24 @@ func hwcapInit(os string) { // TODO(elias.naur): Only disable the optimization on bad chipsets on android. ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android" - // Check to see if executing on a NeoverseN1 and in order to do that, + // Check to see if executing on a Neoverse core and in order to do that, // check the AUXV for the CPUID bit. The getMIDR function executes an // instruction which would normally be an illegal instruction, but it's - // trapped by the kernel, the value sanitized and then returned. Without - // the CPUID bit the kernel will not trap the instruction and the process - // will be terminated with SIGILL. + // trapped by the kernel, the value sanitized and then returned. + // Without the CPUID bit the kernel will not trap the instruction and the + // process will be terminated with SIGILL. if ARM64.HasCPUID { midr := getMIDR() part_num := uint16((midr >> 4) & 0xfff) implementor := byte((midr >> 24) & 0xff) - if implementor == 'A' && part_num == 0xd0c { - ARM64.IsNeoverseN1 = true - } - if implementor == 'A' && part_num == 0xd40 { - ARM64.IsNeoverseV1 = true + // d0c - NeoverseN1 + // d40 - NeoverseV1 + // d49 - NeoverseN2 + // d4f - NeoverseV2 + if implementor == 'A' && (part_num == 0xd0c || part_num == 0xd40 || + part_num == 0xd49 || part_num == 0xd4f) { + ARM64.IsNeoverse = true } } } diff --git a/src/runtime/cpuflags_arm64.go b/src/runtime/cpuflags_arm64.go index a0f1d114d8..2ed1811456 100644 --- a/src/runtime/cpuflags_arm64.go +++ b/src/runtime/cpuflags_arm64.go @@ -11,7 +11,7 @@ import ( var arm64UseAlignedLoads bool func init() { - if cpu.ARM64.IsNeoverseN1 || cpu.ARM64.IsNeoverseV1 { + if cpu.ARM64.IsNeoverse { arm64UseAlignedLoads = true } }