MC3302_SDK_V1.1.9_202507281.../bsp/test/perfmon/perfmon.c
2025-11-11 12:08:31 +08:00

200 lines
6.5 KiB
C
Executable File

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#define DDR_MAX_CH 3
#define RBW_CNT_HIGH_MAX_VAL 0xFF
struct perf_info_t {
unsigned int rtrans_cnt;
unsigned int rbw_cnt;
unsigned int rlatency_cnt;
unsigned int wtrans_cnt;
unsigned int wbw_cnt;
unsigned int wlatency_cnt;
unsigned int rbw_cnt_hig;
unsigned int wbw_cnt_hig;
unsigned long long rbw;
unsigned long long wbw;
};
struct timespec64 {
long long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
int main(int argc, char **argv)
{
struct timespec64 *stv,*etv;
unsigned long long start_time, end_time;
unsigned int sample_it = 0, ms = 1000, ddr_clk;
double d_time, res_rbw[DDR_MAX_CH],res_wbw[DDR_MAX_CH],res_tbw = 0.0;
int fd = 0, i;
char *s = (char*)malloc(256);
char *e = (char*)malloc(256);
struct perf_info_t *spi = (struct perf_info_t *)malloc(DDR_MAX_CH *
sizeof(struct perf_info_t));
struct perf_info_t *epi = (struct perf_info_t *)malloc(DDR_MAX_CH *
sizeof(struct perf_info_t));
memset(s,0,256);
memset(e,0,256);
if (argc > 1) {
sample_it = atoi(argv[1]);
ddr_clk = atoi(argv[2]);
} else {
sample_it = 1;
ddr_clk = 1866;
printf("Usage:\r\n");
printf("./perfmon sample_interval_msecs ddr_data_rate\r\n");
printf("Default:\r\n");
printf("./perfmon 1 1866\r\n");
}
fd = open("/dev/perf",O_RDWR);
if (fd < 0) {
printf("open fail!\n");
return -1;
}
read(fd, s, DDR_MAX_CH * 4 * 8 + 8);
for (i = 0; i < DDR_MAX_CH; i++) {
spi[i].rtrans_cnt = *(unsigned int*)(s + (i << 5) + 0x00);
spi[i].rbw_cnt = *(unsigned int*)(s + (i << 5) + 0x04);
spi[i].rlatency_cnt = *(unsigned int*)(s + (i << 5) + 0x08);
spi[i].wtrans_cnt = *(unsigned int*)(s + (i << 5) + 0x0c);
spi[i].wbw_cnt = *(unsigned int*)(s + (i << 5) + 0x10);
spi[i].wlatency_cnt = *(unsigned int*)(s + (i << 5) + 0x14);
spi[i].rbw_cnt_hig = *(unsigned int*)(s + (i << 5) + 0x18);
spi[i].wbw_cnt_hig = *(unsigned int*)(s + (i << 5) + 0x1C);
spi[i].rbw = ((unsigned long long)spi[i].rbw_cnt_hig << 32) |
spi[i].rbw_cnt;
spi[i].wbw = ((unsigned long long)spi[i].wbw_cnt_hig << 32) |
spi[i].wbw_cnt;
#if 0
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x00), spi[i].rtrans_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x04), spi[i].rbw_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x08), spi[i].rlatency_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x0c), spi[i].wtrans_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x10), spi[i].wbw_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x14), spi[i].wlatency_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x18), spi[i].rbw_cnt_hig);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(s +
(i << 5) + 0x1C), spi[i].wbw_cnt_hig);
printf("CH[%d] 0x%016llx 0x%016llx\n", i, spi[i].rbw,
spi[i].wbw);
#endif
}
stv = (struct timespec64*)(s + (6 << 5) + 0x20);
//printf("%llu %lu\n", stv->tv_sec, stv->tv_nsec);
usleep(sample_it * ms);
read(fd, e, DDR_MAX_CH * 4 * 8 + 8);
for (i = 0; i < DDR_MAX_CH; i++) {
epi[i].rtrans_cnt = *(unsigned int*)(e + (i << 5) + 0x00);
epi[i].rbw_cnt = *(unsigned int*)(e + (i << 5) + 0x04);
epi[i].rlatency_cnt = *(unsigned int*)(e + (i << 5) + 0x08);
epi[i].wtrans_cnt = *(unsigned int*)(e + (i << 5) + 0x0c);
epi[i].wbw_cnt = *(unsigned int*)(e + (i << 5) + 0x10);
epi[i].wlatency_cnt = *(unsigned int*)(e + (i << 5) + 0x14);
epi[i].rbw_cnt_hig = *(unsigned int*)(e + (i << 5) + 0x18);
epi[i].wbw_cnt_hig = *(unsigned int*)(e + (i << 5) + 0x1C);
if (epi[i].rbw_cnt_hig < spi[i].rbw_cnt_hig)
epi[i].rbw_cnt_hig += (RBW_CNT_HIGH_MAX_VAL + 1);
if (epi[i].wbw_cnt_hig < spi[i].wbw_cnt_hig)
epi[i].wbw_cnt_hig += (RBW_CNT_HIGH_MAX_VAL + 1);
epi[i].rbw = ((unsigned long long)epi[i].rbw_cnt_hig << 32) |
epi[i].rbw_cnt;
epi[i].wbw = ((unsigned long long)epi[i].wbw_cnt_hig << 32) |
epi[i].wbw_cnt;
#if 0
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x00), epi[i].rtrans_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x04), epi[i].rbw_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x08), epi[i].rlatency_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x0c), epi[i].wtrans_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x10), epi[i].wbw_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x14), epi[i].wlatency_cnt);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x18), epi[i].rbw_cnt_hig);
printf("CH[%d] 0x%08x 0x%08x\n", i, *(unsigned int*)(e +
(i << 5) + 0x1C), epi[i].wbw_cnt_hig);
printf("CH[%d] 0x%016llx 0x%016llx\n", i, epi[i].rbw,
epi[i].wbw);
#endif
}
etv = (struct timespec64*)(e + (6 << 5) + 0x20);
//printf("%llu %lu\n", etv->tv_sec, etv->tv_nsec);
start_time = (unsigned long long)stv->tv_sec * 1000000000 + stv->tv_nsec;
end_time = (unsigned long long)etv->tv_sec * 1000000000 + etv->tv_nsec;
printf("the start_time is %llu \n", start_time);
printf("the end_time is %llu \n", end_time);
d_time = (end_time - start_time) / 1000000000.0;
printf("interval time is %fs\n", d_time);
for (i = 0; i < DDR_MAX_CH; i++) {
res_rbw[i] = (epi[i].rbw - spi[i].rbw) / (d_time * 1000000.0);
res_wbw[i] = (epi[i].wbw - spi[i].wbw) / (d_time * 1000000.0);
res_tbw += (res_rbw[i] + res_wbw[i]);
printf("CH[%d] R : %0.2fMB/s\n", i, res_rbw[i]);
printf("CH[%d] W : %0.2fMB/s\n", i, res_wbw[i]);
if ((epi[i].rlatency_cnt <= spi[i].rlatency_cnt) ||
(epi[i].rtrans_cnt <= spi[i].rtrans_cnt)) {
printf("CH[%d] RL: Monitor OF \n", i);
} else {
printf("CH[%d] RL: %0.8fus \n", i,
1.0 * (epi[i].rlatency_cnt -
spi[i].rlatency_cnt) / (epi[i].rtrans_cnt -
spi[i].rtrans_cnt) / (1.0 * (ddr_clk >> 2)));
}
if ((epi[i].wlatency_cnt <= spi[i].wlatency_cnt) ||
(epi[i].wtrans_cnt <= spi[i].wtrans_cnt)) {
printf("CH[%d] WL: Monitor OF \n", i);
} else {
printf("CH[%d] WL: %0.8fus \n", i,
1.0 * (epi[i].wlatency_cnt -
spi[i].wlatency_cnt) / (epi[i].wtrans_cnt -
spi[i].wtrans_cnt) / (1.0 * (ddr_clk >> 2)));
}
}
printf("Total usage : %0.2fMB/s\n", res_tbw);
printf("DDR efficiency: %0.2f%%\n", 100 * res_tbw / (ddr_clk << 1));
free(spi);
free(epi);
free(s);
free(e);
close(fd);
return 0;
}