From 75eb43f48d4d694a591c7e45795b4fde55e42430 Mon Sep 17 00:00:00 2001 From: Michael Kuron <m.kuron@gmx.de> Date: Sun, 16 Apr 2023 10:19:56 +0200 Subject: [PATCH] RISC-V cacheline zero --- .gitlab-ci.yml | 6 +-- pystencils/backends/riscv_instruction_sets.py | 3 ++ pystencils/include/riscv_v_helpers.h | 49 +++++++++++++++++++ pystencils_tests/test_vectorization.py | 2 +- 4 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 pystencils/include/riscv_v_helpers.h diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f333e761d..376bd38b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -188,11 +188,11 @@ riscv64: image: i10git.cs.fau.de:5005/pycodegen/pycodegen/riscv64 variables: PYSTENCILS_SIMD: "rvv" - QEMU_CPU: "rv64,v=true" + QEMU_CPU: "rv64,v=true,zicboz=true" before_script: - *multiarch_before_script - - sed -i 's/march=native/march=rv64imfdv/g' ~/.config/pystencils/config.json - - sed -i s/g\+\+/clang++/g ~/.config/pystencils/config.json + - sed -i 's/march=native/march=rv64imfdvzicboz/g' ~/.config/pystencils/config.json + - sed -i s/g\+\+/clang++-15/g ~/.config/pystencils/config.json - sed -i 's/fopenmp/fopenmp=libgomp -I\/usr\/include\/riscv64-linux-gnu/g' ~/.config/pystencils/config.json minimal-conda: diff --git a/pystencils/backends/riscv_instruction_sets.py b/pystencils/backends/riscv_instruction_sets.py index 8e0ab7edd..3bfc957b6 100644 --- a/pystencils/backends/riscv_instruction_sets.py +++ b/pystencils/backends/riscv_instruction_sets.py @@ -106,4 +106,7 @@ def get_vector_instruction_set_riscv(data_type='double', instruction_set='rvv'): result['any'] += ' > 0x0' result['all'] += f' == vsetvl_e{bits[data_type]}m1({vl})' + result['cachelineSize'] = 'cachelineSize()' + result['cachelineZero'] = 'cachelineZero((void*) {0})' + return result diff --git a/pystencils/include/riscv_v_helpers.h b/pystencils/include/riscv_v_helpers.h new file mode 100644 index 000000000..1969521ca --- /dev/null +++ b/pystencils/include/riscv_v_helpers.h @@ -0,0 +1,49 @@ +inline void cachelineZero(void * p) { +#ifdef __riscv_zicboz + __asm__ volatile("cbo.zero (%0)"::"r"(p):"memory"); +#endif +} + +inline size_t _cachelineSize() { + // allocate and fill with ones + const size_t max_size = 0x100000; + uint8_t data[2*max_size]; + for (size_t i = 0; i < 2*max_size; ++i) { + data[i] = 0xff; + } + + // find alignment offset + size_t offset = max_size - ((uintptr_t) data) % max_size; + + // zero a cacheline + cachelineZero((void*) (data + offset)); + + // make sure that at least one byte was zeroed + if (data[offset] != 0) { + return SIZE_MAX; + } + + // make sure that nothing was zeroed before the pointer + if (data[offset-1] == 0) { + return SIZE_MAX; + } + + // find the last byte that was zeroed + for (size_t size = 1; size < max_size; ++size) { + if (data[offset + size] != 0) { + return size; + } + } + + // too much was zeroed + return SIZE_MAX; +} + +inline size_t cachelineSize() { +#ifdef __riscv_zicboz + static size_t size = _cachelineSize(); + return size; +#else + return SIZE_MAX; +#endif +} diff --git a/pystencils_tests/test_vectorization.py b/pystencils_tests/test_vectorization.py index 3718770b9..82a8495d2 100644 --- a/pystencils_tests/test_vectorization.py +++ b/pystencils_tests/test_vectorization.py @@ -60,7 +60,7 @@ def test_aligned_and_nt_stores(openmp, instruction_set=instruction_set): if instruction_set in ['sse'] or instruction_set.startswith('avx'): assert 'stream' in ast.instruction_set assert 'streamFence' in ast.instruction_set - if instruction_set in ['neon', 'vsx'] or instruction_set.startswith('sve'): + if instruction_set in ['neon', 'vsx', 'rvv'] or instruction_set.startswith('sve'): assert 'cachelineZero' in ast.instruction_set if instruction_set in ['vsx']: assert 'storeAAndFlushCacheline' in ast.instruction_set -- GitLab