【问题标题】:Why reading disk more frequently makes each read more fast on Linux? QPS1 vs. 50为什么在 Linux 上更频繁地读取磁盘会使每次读取速度更快? QPS1 与 50
【发布时间】:2012-04-05 14:20:36
【问题描述】:

我在一个带有 SATA 磁盘的 linux 机器上对同步读取性能进行了基准测试。对于单线程读取,奇怪的是,较高的 QPS(50) 在读取 300 个条目后平均读取时间为 12 毫秒,而较低的 QPS(1) 在读取相同的 300 个条目后平均读取时间为 63 毫秒。有什么解释吗?

代码和数据如下:

struct Request{
    unsigned long long len;
    unsigned long long offset;
    int                fd;
};

int read_request(Request* request){
    char* buf = (char*)malloc(request->len);
    off_t of = lseek(request->fd,request->offset,SEEK_SET);
    assert(of == request->offset);

    int len = read(request->fd,buf,request->len);
    assert(len == request->len);
    free(buf);
    return 0;
}




 int read_with_qps(Request* request,int request_num,Files* f,int mode,int qps){

    int interval = 1000 / qps;
    struct timeval start,end;
    for(int i  = 0 ; i < request_num ; i++){
        gettimeofday(&start,NULL);
        int ret = read_request(&request[i]);
        gettimeofday(&end,NULL);
        int time_used = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec)/1000;
        fprintf(stderr,"%lld,offset=%lld,len=%lld, read time:%d,ret=%d,mode=%d\n",
                end.tv_sec,request[i].offset,request[i].len,time_used,ret,mode);
        if(time_used < interval){
            usleep((interval - time_used) * 1000);
        }
    }
    return 0;
}

在 QPS=50 的情况下,输出的样本如下所示(在计算平均时间时忽略时间

1332233329,offset=1052299215,len=13186, read time:13,ret=0,mode=1
1332233329,offset=2319646140,len=1612, read time:10,ret=0,mode=1
1332233330,offset=1319250005,len=5654, read time:12,ret=0,mode=1
1332233330,offset=2520376009,len=2676, read time:12,ret=0,mode=1
1332233330,offset=2197548522,len=17236, read time:10,ret=0,mode=1
1332233330,offset=1363242083,len=13734, read time:11,ret=0,mode=1
1332233330,offset=4242210521,len=2003, read time:17,ret=0,mode=1
1332233330,offset=1666337117,len=2207, read time:10,ret=0,mode=1
1332233330,offset=797722662,len=5480, read time:18,ret=0,mode=1
1332233330,offset=1129310678,len=2265, read time:10,ret=0,mode=1

QPS=1,相同的smaple提取:

1332300410,offset=1052299215,len=13186, read time:19,ret=0,mode=1
1332300411,offset=2319646140,len=1612, read time:40,ret=0,mode=1
1332300412,offset=1319250005,len=5654, read time:141,ret=0,mode=1
1332300413,offset=2520376009,len=2676, read time:15,ret=0,mode=1
1332300414,offset=2197548522,len=17236, read time:21,ret=0,mode=1
1332300415,offset=1363242083,len=13734, read time:13,ret=0,mode=1
1332300416,offset=4242210521,len=2003, read time:43,ret=0,mode=1
1332300417,offset=1666337117,len=2207, read time:18,ret=0,mode=1
1332300418,offset=797722662,len=5480, read time:67,ret=0,mode=1
1332300419,offset=1129310678,len=2265, read time:12,ret=0,mode=1

内核版本为:2.6.18-194.el5 SMP x86_64

$ cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

感谢回复

【问题讨论】:

    标签: linux io


    【解决方案1】:

    当您发出一堆查询时,驱动器固件可以将它们排队并根据旋转位置和磁头位置以优化的顺序执行它们(“电梯搜索”),因此它不必等待完整的搜索时间或每个 i/o 请求的磁盘旋转时间。

    如果您缓慢地发出相同的查询,则没有这样的优势。

    【讨论】:

    • 但是读取请求是同步的,即在返回最后一个之前没有发出下一个读取。
    • 并且请求在偏移量方面是高度随机化的,如示例输出所示。
    【解决方案2】:

    blktrace 可以肯定地告诉你,但这可能是由于plugging。简而言之,IO 请求在发送到磁盘之前可能会稍微延迟,这在有许多请求进入并且可以合并时是有益的,但在其他情况下则不然。

    【讨论】:

    • 这真的很有帮助。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 2023-03-09
    • 2014-01-05
    • 1970-01-01
    • 2019-03-28
    • 2013-06-19
    • 2023-01-27
    相关资源
    最近更新 更多