Skip to content

feat: Add support for RISC-V architecture - #3053

Merged
LindaSummer merged 3 commits into
apache:unstablefrom
wanghan-sanechips:unstable
Aug 18, 2025
Merged

feat: Add support for RISC-V architecture#3053
LindaSummer merged 3 commits into
apache:unstablefrom
wanghan-sanechips:unstable

Conversation

@wanghan-sanechips

Copy link
Copy Markdown
Contributor

Changes:

  1. Adding architecture-specific checks in build scripts
  2. Disable LuaJIT due to unsupported architecture
  3. Downgrade TBB to v2021.13.0

Tested on openEuler-RISC-V - compilation passed

@wanghan-sanechips wanghan-sanechips changed the title RISCV: Add support for RISC-V architecture Add support for RISC-V architecture Jul 14, 2025
@wanghan-sanechips wanghan-sanechips changed the title Add support for RISC-V architecture feat: Add support for RISC-V architecture Jul 14, 2025
@wanghan-sanechips
wanghan-sanechips marked this pull request as ready for review July 14, 2025 07:44
@wanghan-sanechips

Copy link
Copy Markdown
Contributor Author

Hi, the workflow for this PR is awaiting maintainer approval. Could someone help review and approve it? Thank you!

Comment thread cmake/rocksdb.cmake Outdated
@git-hulk

Copy link
Copy Markdown
Member

I feel we're unable to maintain this if we cannot check it in CI stage.

@PragmaTwice

Copy link
Copy Markdown
Member

Yeah it would be great if we have CI support for rv support.

Also, why TBB is downgraded? Any reason for this?

@wanghan-sanechips

Copy link
Copy Markdown
Contributor Author

Yeah it would be great if we have CI support for rv support.

Also, why TBB is downgraded? Any reason for this?

  1. The compilation and testing were done on the Pioneer Box SOPHON SG2042.
    I completely agree that adding CI support for RISC-V would be essential for maintaining its support in the long run.

  2. I downgraded TBB due to build failures on RISC-V, caused by the introduction of the -fcf-protection=full compiler flag in TBB v2022.2.0. Both oneTBB/cmake/compilers/Clang.cmake and oneTBB/cmake/compilers/GNU.cmake add this flag for most architectures other than aarch64, Apple, or Android.
    RISC-V is not excluded, so the flag caused the following error during the build:
    cc1plus: error: ‘-fcf-protection=full’ is not supported for this target compilation terminated due to -Wfatal-errors.
    Downgrading to an earlier version of TBB (before v2022.2.0) avoids the problematic flag and allows the build to succeed.

@LindaSummer

LindaSummer commented Jul 17, 2025

Copy link
Copy Markdown
Member

Hi @wanghan-sanechips ,

Thanks very much for your effort! 😊
But it would be hard to maintain a new architecture support without a CI pipeline for validation.
Could you enhance the CI by adding support for RISC-V with some simulators like QEMU?
Here are some resources found on running a simulator in GitHub Actions. I hope this helps you.

Best Regards,
Edward

@wanghan-sanechips

Copy link
Copy Markdown
Contributor Author

Hi @wanghan-sanechips ,

Thanks very much for your effort! 😊 But it would be hard to maintain a new architecture support without a CI pipeline for validation. Could you enhance the CI by adding support for RISC-V with some simulators like QEMU? Here are some resources found on running a simulator in GitHub Actions. I hope this helps you.

Best Regards, Edward

Thank you for the helpful resources! I'll work on enhancing the CI pipeline to add RISC-V support using QEMU simulation. I'll keep you updated on the progress.

@LindaSummer

Copy link
Copy Markdown
Member

Hi @wanghan-sanechips ,

Maybe you could run CI in your forked repo first, just enable the GitHub Actions and trigger by push, or a draft PR in your repo.
This may accelerate the progress of testing and validation without pending in upstream Github Actions approval. 😊

Best Regards,
Edward

@wanghan-sanechips
wanghan-sanechips force-pushed the unstable branch 3 times, most recently from fd40e9c to d2c2d0e Compare July 23, 2025 08:36
@PragmaTwice

Copy link
Copy Markdown
Member

I downgraded TBB due to build failures on RISC-V, caused by the introduction of the -fcf-protection=full compiler flag in TBB v2022.2.0.

Maybe we can try v2022.1.0 instead of v2021.13.0?

Comment thread x.py Outdated
Comment on lines +132 to +136

import platform
if platform.machine() == 'riscv64':
cmake_options += ["-DENABLE_LUAJIT=OFF", "-DENABLE_LUA=ON"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two problems here:

  • -DENABLE_LUA=ON is useless and can be removed.
  • We can move this logic to CMakeLists.txt, e.g.
if(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64")
    set(ENABLE_LUAJIT OFF)
endif()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review! I'll address these issues in the next push.

@wanghan-sanechips

Copy link
Copy Markdown
Contributor Author

Hi @PragmaTwice , the CI test failed in https://github.com/apache/kvrocks/actions/runs/16559876513/job/46918902321?pr=3053, but it might be a flaky test.
Could you help re-run the workflow? Thanks!

@LindaSummer

Copy link
Copy Markdown
Member

Hi @wanghan-sanechips ,

Thanks for your effort!😊

I will review this PR later today.

Best Regards,
Edward

@LindaSummer

Copy link
Copy Markdown
Member

Hi @wanghan-sanechips ,

The cross compile and unit test flow generally LGTM.

We'd better adapt it to the current workflow, just like below.

- name: Ubuntu ARM GCC
os: ubuntu-24.04-arm
compiler: gcc
arm_linux: true
- name: Ubuntu ARM Clang
os: ubuntu-24.04-arm
compiler: clang
arm_linux: true

And the go integration test and kvrocks2redis test should also be executed in our general test flow.
Once it is adapted to the matrix, it should be executed automatically.
For the go client, I think we could just build an x86_64 Linux target for testing.

Best Regards,
Edward

@wanghan-sanechips

wanghan-sanechips commented Aug 5, 2025

Copy link
Copy Markdown
Contributor Author

Hi @wanghan-sanechips ,

The cross compile and unit test flow generally LGTM.

We'd better adapt it to the current workflow, just like below.

- name: Ubuntu ARM GCC
os: ubuntu-24.04-arm
compiler: gcc
arm_linux: true
- name: Ubuntu ARM Clang
os: ubuntu-24.04-arm
compiler: clang
arm_linux: true

And the go integration test and kvrocks2redis test should also be executed in our general test flow. Once it is adapted to the matrix, it should be executed automatically. For the go client, I think we could just build an x86_64 Linux target for testing.

Best Regards, Edward

Thank you for your review and suggestions. I've implemented the changes to adapt the cross-compilation and unit test flow to the current workflow.
The changes are now available in [Commit ee0b4a6]. Please let me know if there are any additional adjustments needed.

@wanghan-sanechips
wanghan-sanechips force-pushed the unstable branch 2 times, most recently from f203520 to ee0b4a6 Compare August 7, 2025 01:45
Comment thread CMakeLists.txt Outdated
Comment on lines +19 to +23
if(DEFINED ENV{RISCV_CROSSCOMPILE})
set(CMAKE_SYSTEM_NAME Linux CACHE STRING "")
set(CMAKE_SYSTEM_PROCESSOR riscv64 CACHE STRING "")
set(CMAKE_CROSSCOMPILING TRUE CACHE BOOL "")
endif()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html

After reading the CMake cross-compiling docs, I wonder if we can maintain some "toolchain files" instead of such intrusive modifications? Also current we rely on an env var "RISCV_CROSSCOMPILE", and it seems not a classic way of tuning cmake files.

@wanghan-sanechips wanghan-sanechips Aug 12, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! I've switched to using proper CMake toolchain files as suggested and removed the RISCV_CROSSCOMPILE env var dependency.

The key improvements made include:
1.Created dedicated toolchain files (cmake/riscv64.cmake) for cross-compilation configurations
2.Removed all dependencies on the RISCV_CROSSCOMPILE environment variable
3.Updated the build system to use -DCMAKE_TOOLCHAIN_FILE for cross-compilation
4.Modified the CI workflows to use the new toolchain file approach

Appreciate the suggestion - this is indeed a cleaner approach.

@LindaSummer LindaSummer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @wanghan-sanechips ,

Leave a comment on Golang integration tests.

Best Regards,
Edward

Comment thread .github/workflows/kvrocks.yaml Outdated
Comment thread cmake/jemalloc.cmake Outdated
Comment on lines +43 to +46
if(NOT DEFINED JEMALLOC_CROSS_FLAGS)
set(JEMALLOC_CROSS_FLAGS "")
endif()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems useless? it is evaluated to empty if it is not defined in cmake.

@PragmaTwice PragmaTwice left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally looks good to me!

@LindaSummer

Copy link
Copy Markdown
Member

Hi @wanghan-sanechips ,

Thank you very much for your excellent work! LGTM 😊

@PragmaTwice , do we need to create a new PR after this to cache the toolchain tarball, which is approximately 600 MB, and should we cache it?

Best Regards,
Edward

@PragmaTwice

Copy link
Copy Markdown
Member

do we need to create a new PR after this to cache the toolchain tarball, which is approximately 600 MB, and should we cache it?

Nope. We do not need to cache it as long as the download time is short.

@PragmaTwice PragmaTwice left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. One last question. As I observed the difference of test executing time (unit test and golang test) between native (x86) and qemu (x86-riscv) is quite small (less than 2x time). Previously I think that the speed can be more than 2x slower because of the riscv -> x86 transpilation. Is it expected?

I checked some benchmark (e.g. rv8 vs qemu: https://michaeljclark.github.io/bench.html) and it seems the performance of qemu is not so good. But maybe kvrocks is more IO-bound (network and file IO) so that the emulation performance (user-mode emulation?) is not critical.

@sonarqubecloud

Copy link
Copy Markdown

@LindaSummer
LindaSummer merged commit 46fa34b into apache:unstable Aug 18, 2025
37 checks passed
@wanghan-sanechips

Copy link
Copy Markdown
Contributor Author

LGTM. One last question. As I observed the difference of test executing time (unit test and golang test) between native (x86) and qemu (x86-riscv) is quite small (less than 2x time). Previously I think that the speed can be more than 2x slower because of the riscv -> x86 transpilation. Is it expected?

I checked some benchmark (e.g. rv8 vs qemu: https://michaeljclark.github.io/bench.html) and it seems the performance of qemu is not so good. But maybe kvrocks is more IO-bound (network and file IO) so that the emulation performance (user-mode emulation?) is not critical.

Thanks for raising this question! I've run more detailed benchmarks using these test cases:

func cpuBound() { /* factorial calculation */ }      // BigInt math
func ioBound() { /* 100x 1MB file writes */ }       // Disk I/O
func hashTest() { /* 10M SHA-256 operations */ }    // Crypto hashing

Results (x86 native vs QEMU RISC-V):

Test Type Native x86 QEMU RISC-V Slowdown
CPU-bound (BigInt) 297ms 953ms 3.2x
SHA-256 Hash 1.14s 24.7s 21.7x
Disk I/O 384ms 470ms 1.2x

These results confirm your suspicion:

  1. Pure computation shows significant slowdown (3-20x) under QEMU emulation
  2. But I/O operations remain close to native speed (just 1.2x slower)

This explains the performance gap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants