From 2aaee8aff97d37e1970875adad87ca2ea95c7d51 Mon Sep 17 00:00:00 2001 From: Igor Walther Date: Wed, 31 Jul 2024 15:02:42 +0300 Subject: [PATCH] feat: add vector addition --- .github/workflows/hw1.yaml | 6 +- .../tests/watchdog_integration_test_server.go | 2 +- .../vector_addition/vector_addition_arm64.s | 32 +++++++++++ .../vector_addition/vector_addition_test.go | 55 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 open_lessons/asm/simd/vector_addition/vector_addition_arm64.s create mode 100644 open_lessons/asm/simd/vector_addition/vector_addition_test.go diff --git a/.github/workflows/hw1.yaml b/.github/workflows/hw1.yaml index 0ad50a8..90f288b 100644 --- a/.github/workflows/hw1.yaml +++ b/.github/workflows/hw1.yaml @@ -4,7 +4,7 @@ # TODO #jobs: -# test: +# vector_addition: # runs-on: ${{ matrix.os }} # strategy: # fail-fast: false @@ -21,6 +21,6 @@ # - name: dependencies # working-directory: ./homeworks/hw1 # run: go mod tidy -# - name: test +# - name: vector_addition # working-directory: ./homeworks/hw1 -# run: go test -v ./... +# run: go vector_addition -v ./... diff --git a/homeworks/hw1/cmd/watchdog/tests/watchdog_integration_test_server.go b/homeworks/hw1/cmd/watchdog/tests/watchdog_integration_test_server.go index 17df8ba..60a8f70 100644 --- a/homeworks/hw1/cmd/watchdog/tests/watchdog_integration_test_server.go +++ b/homeworks/hw1/cmd/watchdog/tests/watchdog_integration_test_server.go @@ -36,7 +36,7 @@ func main() { } if testEnv != "TEST_ENV_DATA" { - panic("test inh mismatch") + panic("vector_addition inh mismatch") } reader := bufio.NewReader(os.Stdin) diff --git a/open_lessons/asm/simd/vector_addition/vector_addition_arm64.s b/open_lessons/asm/simd/vector_addition/vector_addition_arm64.s new file mode 100644 index 0000000..df8ae7b --- /dev/null +++ b/open_lessons/asm/simd/vector_addition/vector_addition_arm64.s @@ -0,0 +1,32 @@ +#include "textflag.h" + +TEXT ·vectorAddition(SB), NOSPLIT, $0 + LDP first_base+0(FP), (R0, R1) + LDP second_base+24(FP), (R2, R3) + LDP dst_base+48(FP), (R4, R5) + + MOVD $0, R7 + MOVD R4, R11 + MOVD R0, R12 + MOVD R2, R13 + +loop: + CMP R5, R7 + BGE done + + VLD1 (R12), [V1.S4] + VLD1 (R13), [V2.S4] + VADD V1.S4, V2.S4, V3.S4 + + VST1 [V3.S4], (R11) + + ADD $4, R7 + + ADD $16, R11 + ADD $16, R12 + ADD $16, R13 + + B loop + +done: + RET diff --git a/open_lessons/asm/simd/vector_addition/vector_addition_test.go b/open_lessons/asm/simd/vector_addition/vector_addition_test.go new file mode 100644 index 0000000..cdd800b --- /dev/null +++ b/open_lessons/asm/simd/vector_addition/vector_addition_test.go @@ -0,0 +1,55 @@ +package main + +import ( + "math/rand/v2" + "testing" +) + +func vectorAddition(first, second, dst []uint32) + +func vectorAdditionV0(first, second, dst []uint32) { + for i := 0; i < len(first); i++ { + dst[i] = first[i] + second[i] + } +} + +func BenchmarkAdd(b *testing.B) { + b.Run("SIMD vector addition", func(b *testing.B) { + b.StopTimer() + f, s, dst := getData() + b.StartTimer() + + for i := 0; i < b.N; i++ { + vectorAddition(f, s, dst) + } + }) + + b.Run("simple vector addition", func(b *testing.B) { + b.StopTimer() + f, s, dst := getData() + b.StartTimer() + + for i := 0; i < b.N; i++ { + vectorAdditionV0(f, s, dst) + } + }) +} + +// assume alignment +func getData() ([]uint32, []uint32, []uint32) { + first := make([]uint32, 1_000_000) + + for i := 0; i < len(first); i++ { + first[i] = rand.N[uint32](5) + } + + second := make([]uint32, 1_000_000) + + for i := 0; i < len(second); i++ { + second[i] = rand.N[uint32](5) + } + + dst := make([]uint32, 1_000_000) + + return first, second, dst +}