Доступ к аппаратным счетчикам производительности в RIS C -V - PullRequest
3 голосов
/ 04 февраля 2020

Я хотел бы использовать программу для доступа к аппаратным счетчикам производительности.

Я скомпилировал базовый c Rocketchip (freechips.rocketchip.system-DefaultConfig) и использую riscv-pk для запуска двоичного файла. Я запускаю симуляцию ядра в Verilator, скомпилировав все это по умолчанию в проекте UCB Chipyard.

C для двоичного файла выглядит следующим образом:

#include <stdio.h>

#define CACHE_MISS      0x100

int loop(int n, int a) {
        int b = 0;
        for(int i=0; i<n; i++) {
                b = a + b;
        }
        return b;
}

int main() {
        int a = 1;
        int n = 200;
        int count = 0;

        printf("Configuring event monitor ...\n");
        /*
        // initialize counters here
        // should start tracking cache misses with 0x100
        __asm__ volatile("csrw mhpmevent3, %0"
                                :
                                : "r"(CACHE_MISS)
                        );
        */
        printf("Executing loop ...\n");
        loop(n, a);

        printf("Reading event counter ...\n");
        // read counters here
        __asm__ volatile("csrr %0, hpmcounter3"
                                : "=r"(count)
                        );
        printf("Cache misses: %d\n", count);
        return 0;
}

Это базовый c код только для того, чтобы узнать, могу ли я считать ошибки в кеше. Этот код дает мне ошибку «недопустимая инструкция».

z  0000000000000000 ra 00000000000101e0 sp 000000000fee9b00 gp 000000000001e560
tp 0000000000000000 t0 0000000000000000 t1 000000000000000f t2 0000000000000000
s0 000000000fee9b20 s1 0000000000000000 a0 00000000000000c8 a1 0000000000000001
a2 0000000000000000 a3 0000000000000010 a4 00000000000000c8 a5 00000000000000c8
a6 000000000000001f a7 0000000000000000 s2 0000000000000000 s3 0000000000000000
s4 0000000000000000 s5 0000000000000000 s6 0000000000000000 s7 0000000000000000
s8 0000000000000000 s9 0000000000000000 sA 0000000000000000 sB 0000000000000000
t3 0000000000000000 t4 0000000000000000 t5 0000000000000000 t6 0000000000000000
pc 00000000000101e0 va 00000000b03027f3 insn       b03027f3 sr 8000000200046020
An illegal instruction was executed!

Первоначально строка, которая читала из hpmcounter3, читала из mhpmcounter3 и приводила к той же ошибке.

Говоря с Другой разработчик, одной из возможных причин этого является тот факт, что riscv-pk запускает двоичные файлы в U-режиме, поэтому ожидается недопустимая инструкция после вызова m* инструкций по сборке (которые выполняются в Machine, M-mode). Таким образом, я изменил двоичный файл, чтобы закомментировать первую запись в mphmevent3, и просто прочитал ее из hpmcounter3, но все равно получил ошибку недопустимой инструкции. Теория для этого результата состояла в том, что регистры mcounteren и scounteren не были включены, поэтому я не мог получить доступ к счетчикам. Однако, заглянув внутрь riscv-pk minit.c, я обнаружил:

  // Enable user/supervisor use of perf counters
  if (supports_extension('S'))
    write_csr(scounteren, -1);
  if (supports_extension('U'))
    write_csr(mcounteren, -1);

Я не уверен, но я чувствую, что это позволяет счетчикам.

Любые мысли о как мне go получить доступ к аппаратным счетчикам производительности?

1 Ответ

2 голосов
/ 08 февраля 2020

Да, pk запускает двоичные файлы в пользовательском режиме, поэтому ожидается, что доступ к регистру уровня компьютера из пространства пользователя приведет к недопустимому исключению инструкции:

Попытки получить доступ к CSR без соответствующего уровня привилегий или запись в регистр только для чтения также вызывает недопустимые исключения инструкций.

( RIS C -V Privileged spe c 1.12-draft 2020-01-13 , Section 2.1 Соглашения о сопоставлении адресов CSR)

Регистры hpmcounter* доступны из пользовательского режима (см. Таблицу 2.2. В настоящее время выделены адреса CSR RIS C -V на уровне пользователя, привилегированные RIS C -V). c), если и только если они включены в следующем более высоком режиме:

Если реализован S-режим, одинаковые позиции битов в регистре scounteren аналогично управляют доступом к этим регистрам при выполнении в U-режиме. Если в S-режиме разрешен доступ к регистру счетчика и соответствующий бит установлен в scounteren, то в U-режиме также разрешен доступ к этому регистру.

Фрагмент pk, который позволяет им выглядеть звуковым. Биты 'S' и 'U' misa определены в привилегированной RIS C -V spe c:

Биты «U» и «S» будут установлены, если есть поддержка режимов пользователя и супервизора соответственно.

Но обратите внимание, что привилегированная спецификация RIS C -V c также указывает (выделено мое):

Регистры mcounteren и scounteren - это регистры WARL, которые должны быть реализованы, если реализованы U-режим и S-режим. Любой из битов может содержать аппаратное значение, равное нулю , указывая, что чтение к соответствующему счетчику вызовет исключение недопустимой инструкции при выполнении в менее привилегированном режиме.

Возможно, ваш процессор не реализует hpmcounter3 и имеет ли он аппаратно обнуленный ноль?

Чтобы устранить эту проблему, вы можете добавить точку останова внутри pk, т. Е. Прямо перед write_csr(scounteren, -1) и одношаговые инструкции ассемблера чтобы увидеть, если записи действительно происходят. Если они произошли, вы можете проверить регистры, чтобы убедиться, что hpmcounter3 подключен к нулю или нет.

...