Files
Linux_Drivers/build/tools/common/profileSD/profileSD.c
sam.xiang a4f213ceb0 [build] add cvitek build scripts
Change-Id: If63ce4a669e5d4d72b8e3b9253336dd99bf74c30
2023-03-10 20:35:59 +08:00

393 lines
12 KiB
C

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.h>
#define KB(x) (x<<10)
#define MB(x) (x<<20)
#define GB(x) (x<<30)
#define FIX_DATA_SIZE KB(512) // 512KB each time
#define RAND_NUM_DATA_SIZE (21)
char mode[5];
char op_mode[8];
int file_op = -1;
char file_path[128];
int repeat_times;
size_t stImageSize;
int fd = 0;
FILE *fp = NULL;
typedef struct _stRandBuf {
char *buf;
size_t buf_size;
} stRandBuf;
enum _eFileOpMode {
SYSTEM_CALL = 0,
FILE_STREAM,
};
static stRandBuf _gstRandBuf[RAND_NUM_DATA_SIZE] = {
{.buf = NULL, .buf_size = 29}, {.buf = NULL, .buf_size = 30290}, {.buf = NULL, .buf_size = 3435},
{.buf = NULL, .buf_size = 235}, {.buf = NULL, .buf_size = 12345}, {.buf = NULL, .buf_size = 80},
{.buf = NULL, .buf_size = 9845}, {.buf = NULL, .buf_size = 564}, {.buf = NULL, .buf_size = 34862},
{.buf = NULL, .buf_size = 123}, {.buf = NULL, .buf_size = 267890}, {.buf = NULL, .buf_size = 36},
{.buf = NULL, .buf_size = 6788}, {.buf = NULL, .buf_size = 86}, {.buf = NULL, .buf_size = 234567},
{.buf = NULL, .buf_size = 1232}, {.buf = NULL, .buf_size = 514}, {.buf = NULL, .buf_size = 50},
{.buf = NULL, .buf_size = 678}, {.buf = NULL, .buf_size = 9864}, {.buf = NULL, .buf_size = 333333},
};
static void inline drop_cache(void)
{
system("echo 3 > /proc/sys/vm/drop_caches");
}
static double MeasureFIX_WriteSpeed(char *buf, size_t buf_size, size_t total)
{
struct timeval start, end;
double Speed_in_MB = 0, time_in_s = 0;
size_t cur_size = 0;
memset(buf, 0x1F, buf_size);
if (file_op == SYSTEM_CALL) {
lseek(fd, 0x0, SEEK_SET);
} else if (file_op == FILE_STREAM) {
fseek(fp, 0x0, SEEK_SET);
}
drop_cache();
if (file_op == SYSTEM_CALL) {
gettimeofday(&start, NULL);
do {
cur_size += write(fd, buf, buf_size);
} while( cur_size < total);
gettimeofday(&end, NULL);
} else if (file_op == FILE_STREAM) {
gettimeofday(&start, NULL);
do {
fwrite(buf , buf_size, 1, fp);
cur_size += buf_size;
} while( cur_size < total);
fsync(fileno(fp));
gettimeofday(&end, NULL);
}
time_in_s = (double)((end.tv_sec - start.tv_sec) +
((end.tv_usec - start.tv_usec) / 1000000.0));
Speed_in_MB = (double)(cur_size/MB(1)/time_in_s);
printf("Total write size: %zu Bytes\n", cur_size);
printf("Write size each time: %zu Bytes\n", buf_size);
printf("Write time: %f Seconds\n", (double)time_in_s);
printf("Write speed: %f MB/s\n", (double)Speed_in_MB);
return Speed_in_MB;
}
static double MeasureFIX_ReadSpeed(char *buf, size_t buf_size, size_t total)
{
struct timeval start, end;
double Speed_in_MB = 0, time_in_s = 0;
size_t cur_size = 0;
memset(buf, 0x1F, buf_size);
if (file_op == SYSTEM_CALL) {
lseek(fd, 0x0, SEEK_SET);
} else if (file_op == FILE_STREAM) {
fseek(fp, 0x0, SEEK_SET);
}
drop_cache();
if (file_op == SYSTEM_CALL) {
gettimeofday(&start, NULL);
do {
cur_size += read(fd, buf, buf_size);
} while( cur_size < total);
gettimeofday(&end, NULL);
} else if (file_op == FILE_STREAM) {
gettimeofday(&start, NULL);
do {
fread(buf , buf_size, 1, fp);
cur_size += buf_size;
} while( cur_size < total);
gettimeofday(&end, NULL);
}
time_in_s = (double)((end.tv_sec - start.tv_sec) +
((end.tv_usec - start.tv_usec) / 1000000.0));
Speed_in_MB = (double)(cur_size/MB(1)/time_in_s);
printf("Total read size: %zu Bytes\n", cur_size);
printf("Read size each time: %zu Bytes\n", buf_size);
printf("Read time: %f Seconds\n", (double)time_in_s);
printf("Read speed: %f MB/s\n", (double)Speed_in_MB);
return Speed_in_MB;
}
static double MeasureRAND_WriteSpeed(size_t total)
{
struct timeval start, end;
double Speed_in_MB = 0, time_in_s = 0;
size_t cur_size = 0;
int i;
for (i = 0; i < RAND_NUM_DATA_SIZE; i++)
memset(_gstRandBuf[i].buf, 0x1F, _gstRandBuf[i].buf_size);
if (file_op == SYSTEM_CALL) {
lseek(fd, 0x0, SEEK_SET);
} else if (file_op == FILE_STREAM) {
fseek(fp, 0x0, SEEK_SET);
}
drop_cache();
if (file_op == SYSTEM_CALL) {
gettimeofday(&start, NULL);
for (i = 0; i < RAND_NUM_DATA_SIZE && cur_size < total; i++) {
cur_size += write(fd, _gstRandBuf[i].buf, _gstRandBuf[i].buf_size);
if (i == RAND_NUM_DATA_SIZE - 1)
i = 0;
}
gettimeofday(&end, NULL);
} else if (file_op == FILE_STREAM) {
gettimeofday(&start, NULL);
for (i = 0; i < RAND_NUM_DATA_SIZE && cur_size < total; i++) {
fwrite(_gstRandBuf[i].buf, _gstRandBuf[i].buf_size, 1, fp);
cur_size += _gstRandBuf[i].buf_size;
if (i == RAND_NUM_DATA_SIZE - 1)
i = 0;
}
fsync(fileno(fp));
gettimeofday(&end, NULL);
}
time_in_s = (double)((end.tv_sec - start.tv_sec) +
((end.tv_usec - start.tv_usec) / 1000000.0));
Speed_in_MB = (double)(cur_size/MB(1)/time_in_s);
printf("Total write size: %zu Bytes\n", cur_size);
printf("Write time: %f Seconds\n", (double)time_in_s);
printf("Write speed: %f MB/s\n", (double)Speed_in_MB);
return Speed_in_MB;
}
static double MeasureRAND_ReadSpeed(size_t total)
{
struct timeval start, end;
double Speed_in_MB = 0, time_in_s = 0;
size_t cur_size = 0;
int i;
for (i = 0; i < RAND_NUM_DATA_SIZE; i++)
memset(_gstRandBuf[i].buf, 0x1F, _gstRandBuf[i].buf_size);
if (file_op == SYSTEM_CALL) {
lseek(fd, 0x0, SEEK_SET);
} else if (file_op == FILE_STREAM) {
fseek(fp, 0x0, SEEK_SET);
}
drop_cache();
if (file_op == SYSTEM_CALL) {
gettimeofday(&start, NULL);
for (i = 0; i < RAND_NUM_DATA_SIZE && cur_size < total; i++) {
cur_size += read(fd, _gstRandBuf[i].buf, _gstRandBuf[i].buf_size);
if (i == RAND_NUM_DATA_SIZE - 1)
i = 0;
}
gettimeofday(&end, NULL);
} else if (file_op == FILE_STREAM) {
gettimeofday(&start, NULL);
for (i = 0; i < RAND_NUM_DATA_SIZE && cur_size < total; i++) {
fread(_gstRandBuf[i].buf, _gstRandBuf[i].buf_size, 1, fp);
cur_size += _gstRandBuf[i].buf_size;
if (i == RAND_NUM_DATA_SIZE - 1)
i = 0;
}
gettimeofday(&end, NULL);
}
time_in_s = (double)((end.tv_sec - start.tv_sec) +
((end.tv_usec - start.tv_usec) / 1000000.0));
Speed_in_MB = (double)(cur_size/MB(1)/time_in_s);
printf("Total read size: %zu Bytes\n", cur_size);
printf("Read time: %f Seconds\n", (double)time_in_s);
printf("Read speed: %f MB/s\n", (double)Speed_in_MB);
return Speed_in_MB;
}
static size_t _parseTotalSize(char *input)
{
char ImageSize[128];
if (strcspn(input, "K") < strlen(input)) {
strncpy(ImageSize, input, strcspn(input, "K"));
return KB(atol(ImageSize));
} else if (strcspn(input, "M") < strlen(input)) {
strncpy(ImageSize, input, strcspn(input, "M"));
return MB(atol(ImageSize));
} else if (strcspn(input, "G") < strlen(input)) {
strncpy(ImageSize, input, strcspn(input, "G"));
return GB(atol(ImageSize));
}
return 0;
}
int main(int argc, char *argv[])
{
if (argc == 6) {
strncpy(mode, argv[1], sizeof(mode));
strncpy(op_mode, argv[2], sizeof(op_mode));
repeat_times = atoi(argv[3]);
strncpy(file_path, argv[4], sizeof(file_path));
stImageSize = _parseTotalSize(argv[5]);
if (repeat_times <= 0) {
printf("Repeat:%d is invalid, set default value\n", repeat_times);
repeat_times = 1;
}
if (stImageSize < FIX_DATA_SIZE) {
printf("Please check TOTAL_SIZE:%zu, should be larger than 512KB\n", stImageSize);
goto EXIT;
}
if ((0 != strcmp(op_mode, "SYSCALL")) && (0 != strcmp(op_mode, "STREAM"))) {
printf("Please check OP argument: %s, should be either SYSCALL or STREAM\n", op_mode);
goto EXIT;
} else {
if (!strcmp(op_mode, "SYSCALL"))
file_op = SYSTEM_CALL;
else if(!strcmp(op_mode, "STREAM"))
file_op = FILE_STREAM;
}
} else {
if ((argc == 2) &&
((0 == strcmp(argv[1], "--help")) || (0 == strcmp(argv[1], "-h")))) {
printf("==================Usage==================\n");
printf("profileSD [MODE] [OP] [LOOP] [PATH] [SIZE]\n");
printf("[MODE]: FIX\n");
printf("write/read data in the fixed length of 512 KBytes in a single channel.\n");
printf("-\n");
printf("[MODE]: RAND\n");
printf("randomly and cyclically write/read data in the following different lengths"
"(in bytes) in a single channel: 29, 30290, 3435, 235, 12345, 80, 9845, 564,"
"34862, 123, 267890, 36, 6788, 86, 234567, 1232, 514, 50, 678, 9864, 333333.\n");
printf("-\n");
printf("[OP]: SYSCALL/STREAM\n");
printf("-\n");
printf("[LOOP]: Repeat Times: default 1\n");
printf("-\n");
printf("[PATH]: Generated file path\n");
printf("-\n");
printf("[LOOP]: Generated file size\n");
printf("==================Example==================\n");
printf("./BinaryName MODE OP LOOP PATH SIZE\n");
printf("./profileSD FIX SYSCALL 5 \"/mnt/sd/test.img\" 1024MB\n");
printf("./profileSD RAND STREAM 5 \"/mnt/sd/test.img\" 1GB\n");
} else {
printf("==================Usage==================\n");
printf("profileSD [MODE] [OP] [LOOP] [PATH] [SIZE]\n");
printf("Try 'profileSD --help' for more information.\n");
}
goto EXIT;
}
if (0 == strcmp(mode ,"FIX")) {
if (file_op == SYSTEM_CALL) {
fd = open(file_path, O_CREAT | O_RDWR | O_SYNC, 0666);
} else if (file_op == FILE_STREAM) {
fp = fopen(file_path, "w+");
}
char *Buffer = NULL;
if (fd > 0 || fp != NULL) {
double AvrWSpeedMB = 0, AvrRSpeedMB = 0;
int loop = 1;
Buffer = malloc(FIX_DATA_SIZE);
if (Buffer == NULL)
goto EXIT;
printf("==================Test Start==================\n");
printf("Generate File name: %s, mode:%s operation:%s\n", file_path, mode, op_mode);
printf("(It may cost few seconds, please don't close it.)\n");
do {
printf("*************Trying %d/%d rounds*************\n", loop, repeat_times);
AvrWSpeedMB += MeasureFIX_WriteSpeed(Buffer, FIX_DATA_SIZE, stImageSize);
AvrRSpeedMB += MeasureFIX_ReadSpeed(Buffer, FIX_DATA_SIZE, stImageSize);
loop++;
} while( loop <= repeat_times);
printf("==================Test Result=================\n");
printf("Average WRITE Speed: %f MB/s\n", (double)AvrWSpeedMB/repeat_times);
printf("Average READ speed: %f MB/s\n", (double)AvrRSpeedMB/repeat_times);
printf("==================Test End====================\n");
} else {
fprintf(stderr, "Open %s failed due to %s\n", file_path, strerror(errno));
}
if (Buffer)
free(Buffer);
if (fd)
close(fd);
if (fp)
fclose(fp);
} else if (0 == strcmp(mode ,"RAND")) {
int i = 0;
if (file_op == SYSTEM_CALL) {
fd = open(file_path, O_CREAT | O_RDWR | O_SYNC, 0666);
} else if (file_op == FILE_STREAM) {
fp = fopen(file_path, "w+");
}
if (fd > 0 || fp != NULL) {
double AvrWSpeedMB = 0, AvrRSpeedMB = 0;
int loop = 1;
for (i = 0; i < RAND_NUM_DATA_SIZE; i++) {
_gstRandBuf[i].buf = malloc(_gstRandBuf[i].buf_size);
if (_gstRandBuf[i].buf == NULL) {
printf("Allocate %d buffer failed, size: %zu\n", i, _gstRandBuf[i].buf_size);
goto EXIT;
}
}
printf("==================Test Start==================\n");
printf("Generate File name: %s mode:%s operation:%s\n", file_path, mode, op_mode);
printf("(It may cost few seconds, please don't close it.)\n");
do {
printf("*************Trying %d/%d rounds*************\n", loop, repeat_times);
AvrWSpeedMB += MeasureRAND_WriteSpeed(stImageSize);
AvrRSpeedMB += MeasureRAND_ReadSpeed(stImageSize);
loop++;
} while( loop <= repeat_times);
printf("==================Test Result=================\n");
printf("Average WRITE Speed: %f MB/s\n", (double)AvrWSpeedMB/repeat_times);
printf("Average READ speed: %f MB/s\n", (double)AvrRSpeedMB/repeat_times);
printf("==================Test End====================\n");
} else {
fprintf(stderr, "Open %s failed due to %s\n", file_path, strerror(errno));
}
for (i = 0; i < RAND_NUM_DATA_SIZE; i++) {
if(_gstRandBuf[i].buf) {
free(_gstRandBuf[i].buf);
_gstRandBuf[i].buf = NULL;
}
}
if (fd)
close(fd);
if (fp)
fclose(fp);
}
EXIT:
return 0;
}