c – 优化磁盘IO

前端之家收集整理的这篇文章主要介绍了c – 优化磁盘IO前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一段代码可以分析来自非常大(10-100GB)二进制文件的数据流.它运行良好,所以是时候开始优化了,目前磁盘IO是最大的瓶颈.

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

  1. int64_t read_current_chimera(FILE *input,double *current,int64_t position,int64_t length,chimera *daqsetup)
  2. {
  3. int64_t test;
  4. uint16_t iv;
  5.  
  6. int64_t i;
  7. int64_t read = 0;
  8.  
  9. if (fseeko64(input,(off64_t)position * sizeof(uint16_t),SEEK_SET))
  10. {
  11. return 0;
  12. }
  13.  
  14. for (i = 0; i < length; i++)
  15. {
  16. test = fread(&iv,sizeof(uint16_t),1,input);
  17. if (test == 1)
  18. {
  19. read++;
  20. current[i] = chimera_gain(iv,daqsetup);
  21. }
  22. else
  23. {
  24. perror("End of file reached");
  25. break;
  26. }
  27. }
  28. return read;
  29. }

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

第二种文件类型包含64位双精度数,但它包含两列,其中我只需要第一列.要做到这一点,我会双击双打并丢弃第二个双打.双重必须在使用前进行字节交换.我用来做这个的代码如下:

  1. int64_t read_current_double(FILE *input,int64_t length)
  2. {
  3. int64_t test;
  4. double iv[2];
  5.  
  6. int64_t i;
  7. int64_t read = 0;
  8.  
  9. if (fseeko64(input,(off64_t)position * 2 * sizeof(double),SEEK_SET))
  10. {
  11. return 0;
  12. }
  13.  
  14. for (i = 0; i < length; i++)
  15. {
  16. test = fread(iv,sizeof(double),2,input);
  17. if (test == 2)
  18. {
  19. read++;
  20. swapByteOrder((int64_t *)&iv[0]);
  21. current[i] = iv[0];
  22. }
  23. else
  24. {
  25. perror("End of file reached: ");
  26. break;
  27. }
  28. }
  29. return read;
  30. }

任何人都可以建议一种读取这些文件类型的方法,这种方法比我目前要快得多吗?

解决方法

首先,使用 profiler识别程序中的 hot spots会很有用.根据您对问题的描述,您会有大量的开销.由于文件很大,增加每个io读取的数据量会有很大的好处.

通过组合2个读取流的小程序来说服自己.

  1. 1) read it as you are in the example above,of 2 doubles.
  2.  
  3. 2) read it the same way,but make it 10,000 doubles.

时间都运行了几次,你可能会观察到#2的运行速度要快得多.

祝你好运.

猜你在找的C&C++相关文章