Опубликован: 24.11.2024 | Доступ: свободный | Студентов: 1 / 0 | Длительность: 02:06:00
Лекция 7:

Лабораторная работа

< Лекция 6 || Лекция 7: 123

Данная лабораторная работа подготовлена Кириленко Яковом Александровичем по заказу Альянса RISC-V, допускается к использованию под лицензией CC BY 4.0.

Приведённые ниже команды рассчитаны на выполнение в рабочей среде Syntacore Kit, распространяемой Альянсом RISC-V в образовательных целях. Обратите внимание, что в другом окружении приведённые примеры команд могут не работать или работать иначе.

Рассмотрите программу, считающую скалярное произведение векторов.

main.c

#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 следующие строки (пути зависят от версии используемой рабочей среды):

Если переменая RISCV не определена

export GCC_ROOT="/opt/syntacore/sc-dt/2023.08/riscv-gcc"
export PATH=$PATH:/opt/syntacore/sc-dt/2023.08/tools/bin

Если переменая RISCV определена

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)
< Лекция 6 || Лекция 7: 123