はじめに
Vortex をビルドしてみた (その2)
./ci/blackbox.sh --driver=rtlsim --clusters=2 --cores=2 --warps=2 --threads=4 --app=basic
の --app=basic の中身をみてみます。
basic
tests/regression/basic の下の kernel.bin が RISC-V の 32ビットのelfファイルのようです。
cd tests/regression/basic ls Makefile basic common.h kernel.bin kernel.c kernel.dump kernel.elf main.cpp ramulator.ddr4.log file kernel.* kernel.bin: data kernel.c: C source, ASCII text kernel.dump: ASCII text kernel.elf: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped
この kernel.bin を
- rtlsim
- simx
- vlsim
の3つのターゲットで実行します。
kernel.c
kernel.c は、アドレス KERNEL_ARG_DEV_MEM_ADDR に書き込まれた引数を使って、src_addr から dst_addr へcount * 4バイト(uint32_t) 分、コピーしています。これが vortex 内で実行われるんですね。
cat kernel.c #include <stdint.h> #include <vx_intrinsics.h> #include "common.h" void main() { kernel_arg_t* arg = (kernel_arg_t*)KERNEL_ARG_DEV_MEM_ADDR; uint32_t count = arg->count; int32_t* src_ptr = (int32_t*)arg->src_addr; int32_t* dst_ptr = (int32_t*)arg->dst_addr; uint32_t offset = vx_core_id() * count; for (uint32_t i = 0; i < count; ++i) { dst_ptr[offset + i] = src_ptr[offset + i]; } }
demo
tests/regression/demo の下の kernel.bin も basic と同様に RISC-V の 32ビットのelfファイルのようです。
cd tests/regression/demo ls Makefile common.h demo kernel.bin kernel.c kernel.dump kernel.elf main.cpp file kernel.* kernel.bin: data kernel.c: C source, ASCII text kernel.dump: ASCII text kernel.elf: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped
kernel.c
こちらの kernel.c は、basic の kernel.c と非常に似ています。kernel_body 関数が basic の kernel.c の main 関数の中とほぼ同じです。
main 関数では、vx_spawn_tasks 関数を使って、kernel_body 関数を 引数 (arg) で呼び出しています。この arg は basic の main 関数内の arg と同じです。
cat kernel.c #include <stdint.h> #include <vx_intrinsics.h> #include <vx_spawn.h> #include "common.h" void kernel_body(int task_id, kernel_arg_t* arg) { uint32_t count = arg->task_size; int32_t* src0_ptr = (int32_t*)arg->src0_addr; int32_t* src1_ptr = (int32_t*)arg->src1_addr; int32_t* dst_ptr = (int32_t*)arg->dst_addr; uint32_t offset = task_id * count; for (uint32_t i = 0; i < count; ++i) { dst_ptr[offset+i] = src0_ptr[offset+i] + src1_ptr[offset+i]; } } void main() { kernel_arg_t* arg = (kernel_arg_t*)KERNEL_ARG_DEV_MEM_ADDR; vx_spawn_tasks(arg->num_tasks, (vx_spawn_tasks_cb)kernel_body, arg);
vx_spawn_task 関数は、runtime/vx_apawn.c の中で定義されています。
おわりに
--app=basic と --app=demo の中をみてみました