Лабораторная работа
Данная лабораторная работа подготовлена Кириленко Яковом Александровичем по заказу Альянса RISC-V, допускается к использованию под лицензией CC BY 4.0.
Приведённые ниже команды рассчитаны на выполнение в рабочей среде Syntacore Kit, распространяемой Альянсом RISC-V в образовательных целях. Обратите внимание, что в другом окружении приведённые примеры команд могут не работать или работать иначе.
Рассмотрите программу, считающую скалярное произведение векторов.
#include <stdlib.h> #include <stdio.h> #include <memory.h> #include <time.h> #include <malloc.h> const size_t N = 200000; const size_t K = 2000; typedef float cell_t; typedef cell_t * cell_ptr_t; cell_t dot_product(cell_ptr_t a, cell_ptr_t b, size_t n) { cell_t r = 0; for (size_t i = 0; i < n; ++i) { r += a[i] * b[i]; } return r; } cell_ptr_t allocate() { cell_ptr_t r = (cell_t*) malloc(sizeof(cell_t) * N); for (size_t i = 1; i < N; ++i) { r[i] = (cell_t) (N * rand() / RAND_MAX); } return r; } int main() { srand(0); // reproducible PRNG cell_ptr_t a = allocate(); cell_ptr_t b = allocate(); cell_t r1 = 0; clock_t t = clock(); for (size_t i = 0; i < K; ++i) { int x = (t % (i + 1)); // some number to force dot_product call r1 += dot_product( (x & 2) ? a : b , (x & 1) ? b : a , N); } double time1 = (double)(clock()-t)/CLOCKS_PER_SEC; printf("%.3g\n%.3g\n" , r1 , time1); free((void *)a); free((void *)b); return 0; }
Кросс-компиляция и запуск
Перед выполнением команд проверьте, определены ли переменные GCC_ROOT или RISCV и указан ли в переменной PATH путь /opt/syntacore/sc-dt/2023.08/tools/ (2023.08-версия Syntacore Kit):
env | grep 'GCC_ROOT\|RISCV' echo $PATH
Если нет, добавьте в файл ~/.bashrc следующие строки (пути зависят от версии используемой рабочей среды):
Если переменая не определена
export GCC_ROOT="/opt/syntacore/sc-dt/2023.08/riscv-gcc" export PATH=$PATH:/opt/syntacore/sc-dt/2023.08/tools/bin
Если переменая определена
export GCC_ROOT=$RISCV export PATH=$PATH:/opt/syntacore/sc-dt/2023.08/tools/bin
Скомпилируйте программу под RISC-V. В Syntacore Kit для систем компиляции GCC и CLang это делается следующими способами:
GCC | CLang |
riscv64-unknown-linux-gnu-gcc main.c -o main |
clang -target riscv64-unknown-linux-gnu --sysroot="$GCC_ROOT/sysroot" --gcc-toolchain="$GCC_ROOT" -o main main.c |
Убедитесь, что полученный исполняемый файл предназначен для RISC?V:
file ./main ./main: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, not stripped
Запустите скомпилированную программу в эмуляторе qemu:
qemu-riscv64 -L "$GCC_ROOT/sysroot" ./main
Отладка
Скомпилируйте программу под RISC-V c отладочной информацией, выставив флаг -g:
GCC | CLang |
riscv64-unknown-linux-gnu-gcc -g main.c -o main |
clang -target riscv64-unknown-linux-gnu --sysroot="$GCC_ROOT/sysroot" --gcc-toolchain="$GCC_ROOT" -g -o main main.c |
Запустите qemu с сервером GDB на произвольном порту, например 12345:
qemu-riscv64 -L $GCC_ROOT/sysroot -g 12345 ./main
Он будет ждать подключения GDB. Затем запустите GDB из системы компиляции для RISC-V (с использованием отладочных символов из файла ./main):
riscv64-unknown-linux-gnu-gdb ./main
В консоли GDB подключитесь к GDB-серверу, запущенном в qemu:
target remote localhost:12345
Установите sysroot, чтобы GDB мог подгрузить символы используемых динамических библиотек:
set sysroot /opt/syntacore/sc-dt/2023.08/riscv-gcc/sysroot
Затем выставьте точку останова:
b main
Продолжите выполнение программы:
с
Теперь можно отлаживать программу, запущенную в эмуляторе.
Листинг консоли GDB после проделанных операций
GNU gdb (GDB) 13.2 Copyright (C) 2023 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-unknown-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./main... (No debugging symbols found in ./main) (gdb) target remote localhost:12345 Remote debugging using localhost:12345 warning: remote target does not support file transfer, attempting to access files from local filesystem. warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. 0x00007f5ae4fdfb40 in ?? () (gdb) set sysroot /opt/syntacore/sc-dt/2023.08/riscv-gcc/sysroot Reading symbols from /opt/syntacore/sc-dt/2023.08/riscv-gcc/sysroot/lib/ld-linux-riscv64-lp64d.so.1... (No debugging symbols found in /opt/syntacore/sc-dt/2023.08/riscv-gcc/sysroot/lib/ld-linux-riscv64-lp64d.so.1) (gdb) b main Breakpoint 1 at 0x1077e (gdb) c Continuing. Breakpoint 1, 0x000000000001077e in main () (gdb)