测试 RAM 盘和 DISK 盘的文件读写速度

一、目的

1.熟悉类 UNIX 系统的 I/O 设备管理
2.熟悉 MINIX 块设备驱动
3.熟悉 MINIX RAM 盘

二、内容与设计思想

测试 RAM 盘和 DISK 盘的文件读写速度,分析其读写速度 差异原因(可用图表形式体 现在实验报告中)。

三、使用环境

Minix,Moba

四、实验过程

1、增加 RAM 盘: 修改/usr/src/minix/drivers/storage/memory/memory.c ,增加默认的用户 RAM 盘数: RAMDISKS=7。重新编译内核,reboot。
测试 RAM 盘和 DISK 盘的文件读写速度

2、创建设备 mknod /dev/myram b 1 13,查看设备是否创建成功输入 ls /dev/ | grep ram。 实现 buildmyram 初始化工具(用于分配容量)。
测试 RAM 盘和 DISK 盘的文件读写速度

3、参考/usr/src/minix/commands/ramdisk/ramdisk.c,实现 buildmyram.c,但是需要将 KB 单 位修改成 MB。
测试 RAM 盘和 DISK 盘的文件读写速度测试 RAM 盘和 DISK 盘的文件读写速度测试 RAM 盘和 DISK 盘的文件读写速度

4、编译 buildmyram.c 文件,然后执行命令: buildmyram /dev/myram。创建一 个 RAM 盘。
测试 RAM 盘和 DISK 盘的文件读写速度

5、在 ram 盘上创建内存文件系统,mkfs.mfs /dev/myram。将 ram 盘挂载到用户目录下,mount /dev/myram /root/myram,查看是否 挂在成功:输入 df。
测试 RAM 盘和 DISK 盘的文件读写速度

注:重启后用户自定义的ram盘内容会丢失,需要重新设置大小,创建文件系统,并挂载。
6、出现write error错误,应该是因为空间太小了,可以考虑缩小读写次数或者增大磁盘容量,我这里将128MB设置成1GB,这个问题就消失了。
测试 RAM 盘和 DISK 盘的文件读写速度测试 RAM 盘和 DISK 盘的文件读写速度

五、总结

刚开始,因为追求块大小的最大值将其设为65536,导致重复的次数减少设为500,最终得出了disk性能优于ram的结论,与假设矛盾。所以之后将块大小调成4096,而增加重复次数为10000,并且删除myram文件夹里的缓存文件,结论恢复正常,但读操作仍然还有改进空间。
测试 RAM 盘和 DISK 盘的文件读写速度测试 RAM 盘和 DISK 盘的文件读写速度测试 RAM 盘和 DISK 盘的文件读写速度测试 RAM 盘和 DISK 盘的文件读写速度

六、测试代码

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <sys/wait.h>

/* macro */
#define Concurrency 15      // max concurrent process
//#define repeat 500          // repeat times
#define repeat 10000          // repeat times
//#define Blocksize 65536     // max blocksize
#define Blocksize 4096     // max blocksize
#define maxline (50 * 1024) // array size
#define mod 1000000007      // a big prime number

/* global variables */
long long writetext[maxline];                     // testing array
long long readbuff[maxline];                      // buff array
struct timeval starttime, endtime, spendtimeSpec; // used to calculate time
char *filepathdisk[19] =
    {"/usr/disk1.txt", "/usr/disk2.txt", "/usr/disk3.txt", "/usr/disk4.txt",
     "/usr/disk5.txt", "/usr/disk6.txt", "/usr/disk7.txt", "/usr/disk8.txt",
     "/usr/disk9.txt", "/usr/disk10.txt", "/usr/disk11.txt", "/usr/disk12.txt",
     "/usr/disk13.txt", "/usr/disk14.txt", "/usr/disk15.txt", "/usr/disk16.txt",
     "/usr/disk17.txt", "/usr/disk18.txt", "/usr/disk19.txt"};
char *filepathram[19] =
    {"/root/myram/ram_test1", "/root/myram/ram_test2", "/root/myram/ram_test3", "/root/myram/ram_test4",
     "/root/myram/ram_test5", "/root/myram/ram_test6", "/root/myram/ram_test7", "/root/myram/ram_test8",
     "/root/myram/ram_test9", "/root/myram/ram_test10", "/root/myram/ram_test11", "/root/myram/ram_test12",
     "/root/myram/ram_test13", "/root/myram/ram_test14", "/root/myram/ram_test15", "/root/myram/ram_test16",
     "/root/myram/ram_test17", "/root/myram/ram_test18", "/root/myram/ram_test19"};

/* write files */
void write_file(int blocksize, bool isrand, char *filepath)
{
    int fp = open(filepath, O_RDWR | O_CREAT | O_SYNC, 0755);
    if (fp > 0)
    {
        for (int i = 0; i < repeat; i++)
        {
            int x = write(fp, writetext, blocksize);
            if (x < 0)
            {
                printf("write error!");
                break;
            }
            if (!isrand)
                lseek(fp, (repeat-1)*(rand() % blocksize), SEEK_SET);
        }
    }
    else
    {
        printf("open error!");
    }
    lseek(fp, 0, SEEK_SET);
}

/* read files */
void read_file(int blocksize, bool isrand, char *filepath)
{
    int fp = open(filepath, O_RDONLY);
    int i = 0;
    if (fp > 0)
    {
        for (; i < repeat; i++)
        {
            int x = read(fp, readbuff, blocksize);
            if (x < 0)
            {
                printf("read error!\n");
                break;
            }
            if (!isrand)
                lseek(fp, (repeat-1)*(rand() % blocksize), SEEK_SET);
        }
    }
    else
    {
        printf("open error!");
    }
    lseek(fp, 0, SEEK_SET);
}

/* get time left */
long get_time_left(struct timeval starttime, struct timeval endtime)
{
    long spendtime = 1000000 * (endtime.tv_sec - starttime.tv_sec) + (endtime.tv_usec - starttime.tv_usec); /* us */
    return spendtime;
}

void test1()
{
    printf("Ram Sequential Write\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    write_file(block, true, filepathram[i]); //ram sequential write
                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB */
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total
            
            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test2()
{
    printf("Ram Random Write\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    write_file(block, false, filepathram[i]); //ram random write
                    
                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB */
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total
            
            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test3()
{
    printf("Ram Sequential Read\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    read_file(block, true, filepathram[i]);  //ram sequential read

                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB*/
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total
            
            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test4()
{
    printf("Ram Random Read\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    read_file(block, false, filepathram[i]); //ram random read

                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB*/
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total

            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test5()
{
    printf("Disk Sequential Write\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    write_file(block, true, filepathdisk[i]);  //disk sequential write

                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB */
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total

            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test6()
{
    printf("Disk Random Write\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    write_file(block, false, filepathdisk[i]); //disk random write

                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB */
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total

            BLOCK+=block;
            LATENCY+=latency;
            
            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test7()
{
    printf("Disk Sequential Read\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    read_file(block, true, filepathdisk[i]);  //disk sequential read

                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB */
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total

            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
}

void test8()
{
    printf("Disk Random Read\n");
    printf("block\tprocess\tlatency\n");
    
    double BLOCK=0;
	double LATENCY=0;

    for (int block = 64; block <= Blocksize; block *= 2)
    {
        for (int concurrency = 1; concurrency <= Concurrency; concurrency ++)
        {
            gettimeofday(&starttime, NULL);
            for (int i = 0; i < concurrency; i++)
            {
                if (fork() == 0)
                {
                    read_file(block, false, filepathdisk[i]); //disk random read

                    exit(1);
                }
            }

            // wait children to terminate
            while (wait(NULL) != -1)
                ;
            gettimeofday(&endtime, NULL);

            /* calculate the duration, latency, file_MB */
            long alltime = get_time_left(starttime, endtime);                        // get the duration (us)
            double latency = (alltime) / (double)repeat / (double)concurrency;       // single file latency (us)
            double file_MB = (double)block * repeat * concurrency / 1024.0 / 1024.0; // filesize in total

            BLOCK+=block;
            LATENCY+=latency;

            printf("%d\t%d\t%.2f\n", block, concurrency, latency);
        }
        double throughput=BLOCK/LATENCY;
    	printf("%.3f\n",throughput);
    	BLOCK=LATENCY=0;
    }
    
}

int main()
{
    srand((unsigned)time(NULL));
    int i = 0;

    // initial a test array
    for (int j = 0; j < maxline; j++)
        writetext[j] = (j * j * j - 3 * Blocksize * j) % mod;

    test1();
	printf("\n");
    test2();
	printf("\n");
    test3();
	printf("\n");
    test4();
	printf("\n");
    test5();
	printf("\n");
    test6();
	printf("\n");
    test7();
	printf("\n");
    test8();
	printf("\n");


    return 0;
}
上一篇:类的浅拷贝与深拷贝


下一篇:udev配置错误导致的一次问题