はじめに
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 の中をみてみました