优化磁盘IO

我有一段代码可以分析非常大(10-100GB)二进制文件的数据流。 它运行良好,因此是时候开始优化了,目前磁盘IO是最大的瓶颈。

有两种类型的文件正在使用中。 第一种类型的文件由16位整数组成,必须在I / O之后进行缩放以转换为具有物理意义的浮点值。 我以块的形式读取文件,并通过一次读取一个16位代码读取大块数据,执行所需的缩放,然后将结果存储在一个数组中。 代码如下:

int64_t read_current_chimera(FILE *input, double *current,
                             int64_t position, int64_t length, chimera *daqsetup)
{
    int64_t test;
    uint16_t iv;

    int64_t i;
    int64_t read = 0;

    if (fseeko64(input, (off64_t)position * sizeof(uint16_t), SEEK_SET))
    {
        return 0;
    }

    for (i = 0; i < length; i++)
    {
        test = fread(&iv, sizeof(uint16_t), 1, input);
        if (test == 1)
        {
            read++;
            current[i] = chimera_gain(iv, daqsetup);
        }
        else
        {
            perror("End of file reached");
            break;
        }
    }
    return read;
}

chimera_gain函数只需要一个16位整数,对其进行缩放并返回双精度来存储。

第二种文件类型包含64位双打,但它包含两列,其中我只需要第一列。 为了做到这一点,我把双打打成了双,并丢弃了第二个。 双重使用前也必须进行排序。 我用来做到这一点的代码如下:

int64_t read_current_double(FILE *input, double *current, int64_t position, int64_t length)
{
    int64_t test;
    double iv[2];

    int64_t i;
    int64_t read = 0;

    if (fseeko64(input, (off64_t)position * 2 * sizeof(double), SEEK_SET))
    {
        return 0;
    }

    for (i = 0; i < length; i++)
    {
        test = fread(iv, sizeof(double), 2, input);
        if (test == 2)
        {
            read++;
            swapByteOrder((int64_t *)&iv[0]);
            current[i] = iv[0];
        }
        else
        {
            perror("End of file reached: ");
            break;
        }
    }
    return read;
}

任何人都可以提出一种阅读这些文件类型的方法,它比我目前所做的要快得多吗?


首先,使用分析器来确定程序中的热点是很有用的。 根据你对这个问题的描述,你有很多费用都是由开销所造成的。 由于文件很大,因此增加每个io读取的数据量会有很大的好处。

通过将2个阅读流的小程序放在一起来说服你自己。

1) read it as you are in the example above, of 2 doubles.

2) read it the same way, but make it 10,000 doubles.

时间都运行几次,而且你会观察#2的运行速度要快得多。

祝你好运。

链接地址: http://www.djcxy.com/p/92887.html

上一篇: Optimizing disk IO

下一篇: How to speed up heavy conditional formatting rules