RDCYCLE can't calculate the execution time

522 views
Skip to first unread message

Aguech Amira

unread,
Mar 22, 2020, 7:17:55 AM3/22/20
to RISC-V SW Dev

hello,

was trying to run a small C code to measure the execution time of the code. The code is:


#include <stdint.h>
#include "murax.h"

static inline uint32_t rdcyc() {
  uint32_t val;
  asm volatile ("rdcycle %0 ;\n":"=r" (val) ::);
  return val;
}

int main()
{
  int i;
  uint32_t t_beg;
  uint32_t t_end;
  
 t_beg  = rdcyc();

for (i=0; i<100000000; i++);
t_end  = rdcyc();
        printf("Time taken: %d", (t_end-t_beg)/1); // To know the excution time of the loop.
printf ("Start Time: %d \n", t_beg );
printf ("End Time  : %d \n", t_end );
return 0;
}




When I compile and run the code using riscv64-unknown-elf-gcc, it gives the following output:

Time taken: 0
Start Time: 0
End Time  : 0

I think the error comes from the RDCYCLE instruction, because I managed to display a constant (a = 5). Can anyone please tell me the reason, why the RDCYCLE is it not able to count the number of clock.
what is the solution that allows me to calculate the execution time, that we compile a c code with riscv64-unknown-elf, please.


cordially.




Luís Marques

unread,
Mar 22, 2020, 7:31:36 AM3/22/20
to Aguech Amira, RISC-V SW Dev
Your for loop is being optimized away. You need to ensure that the loop actually does something.
In real hardware you'd still see some small increment in the cycle counter between the two reads, but you are probably using spike, which does not increment the counter every cycle, but instead in batches, and without the for loop there aren't enough cycles between the two counter reads.

Best,
Luís

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/272e79dd-05b2-4141-b074-3d48ced6b8b9%40groups.riscv.org.

Aguech Amira

unread,
Mar 22, 2020, 7:54:49 AM3/22/20
to RISC-V SW Dev, amir2...@gmail.com
Thank's for your reply.
I added this line: for (i = 0; i <100000000; i ++) {
a + = 1;}
to increment the constant 'a', but the result is the same. I used SpinalHDL / VexRiscv: A FPGA friendly 32 bit RISC-V ... - GitHub, with the riscv64 toolchaine to compile my code.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-...@groups.riscv.org.

Luís Marques

unread,
Mar 22, 2020, 8:13:08 AM3/22/20
to Aguech Amira, RISC-V SW Dev
On Sun, Mar 22, 2020 at 11:54 AM Aguech Amira <amir2...@gmail.com> wrote:
Thank's for your reply.
I added this line: for (i = 0; i <100000000; i ++) {
a + = 1;}
to increment the constant 'a', but the result is the same. I used SpinalHDL / VexRiscv: A FPGA friendly 32 bit RISC-V ... - GitHub, with the riscv64 toolchaine to compile my code.

The compiler is free to replace that for loop with

a += 100000000;

So that doesn't solve the problem.

Tommy Murphy

unread,
Mar 22, 2020, 8:27:34 AM3/22/20
to RISC-V SW Dev
Isn't rdcycle a u mode instruction?
Are you in u or m mode?

Aguech Amira

unread,
Mar 22, 2020, 8:29:52 AM3/22/20
to RISC-V SW Dev, amir2...@gmail.com
I apologize for the inconvenience, but here is another code that can display an msg.


#include <stdint.h>
#include "murax.h"



static inline uint32_t rdcyc() {
  uint32_t val;
  asm volatile ("rdcycle %0 ;\n":"=r" (val) ::);
  return val;
}

/*
void print(const char*str){
    while(*str){
        uart_write(UART,*str);
        str++;
    }
}
void printf(const char*str){
    print(str);
    uart_write(UART,'\n');
}*/

void delay(uint32_t loops){
    for(int i=0;i<loops;i++){
        int tmp = GPIO_A->OUTPUT;
    }
}


void main() {
  uint32_t t_beg;
  uint32_t t_end;

t_beg     = rdcyc();
    GPIO_A->OUTPUT_ENABLE = 0x0000000F;
    GPIO_A->OUTPUT = 0x00000001;
    printf ("hello world arty a7 v1");
    const int nleds = 4;
    const int nloops = 2000000;
t_end     = rdcyc();
    printf ("Time taken: %d \n",(t_end-t_beg)/1); // To know the excution time of the loop.

    printf ("Start Time: %d \n", t_beg );
    printf ("End Time  : %d \n", t_end );
    while(1){
        for(unsigned int i=0;i<nleds-1;i++){
            GPIO_A->OUTPUT = 1<<i;
            delay(nloops);
        }
        for(unsigned int i=0;i<nleds-1;i++){
            GPIO_A->OUTPUT = (1<<(nleds-1))>>i;
            delay(nloops);
        }
    }
}

void irqCallback(){
}

I add the lines which allows to calculate the execution time and here is the result obtained.

hello world arty a7 v1
Time taken: -2147480232
Start Time: 2
End Time  : 2

consu...@gstardust.com

unread,
Mar 22, 2020, 7:23:12 PM3/22/20
to sw-...@groups.riscv.org

A few things to check:

-  Look at the disassembly to see what the compiler did.  Such as there being two rdcycle instructions, and what's in between does what you think.  (The "volatile" on asm means there probably are two rdcycle instructions, as you're using the results.  The "GPIO_A->OUTPUT" and the whole loop might get optimized out depending on how it's defined, because the result is unused.)

-  If running in M-mode, that might be all, although it may depend on the hardware you're using and how it supports this feature.  If in S-mode, bit 0 of the mcounteren CSR must be set.  If in U-mode, bit 0 of both the mcounteren and scounteren registers must be set.

M

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/0e7d7407-2bd1-41ca-b564-49665365f82a%40groups.riscv.org.
Reply all
Reply to author
Forward
0 new messages