4

我有 1GB 二进制文件,它基本上包含相同类型值的 3D 立方体。使用 fseek 和 fwrite 保存这种具有不同顺序([x,y,z] 或 [zx, y])的多维数据集会花费大量时间。但是其中一个软件包比我的程序要快得多。有什么方法可以使文件写入比使用 fseek/fwrite 更快?

4

3 回答 3

7

您不应该在文件 io 操作的内部循环中使用 fseek。为了使写入功能更快,它们会缓存写入。如果你到处寻找,你会不断地破坏缓存。

在内存中进行所有转换 - 例如在内存中旋转立方体,然后在几个连续的 fwrite 调用中写入文件。

如果您无法在内存中完全转换数据,则在内存中一次组装一个平面并写出每个平面。

@编辑:

在您的情况下,您根本不想使用 fseek 。一个也没有。

做这样的事情:

void writeCubeZYX( int* cubeXYZ, int sizeOfCubeXYZ, FILE* file )
{
   int* cubeZYX = malloc( sizeOfCubeXYZ );

   // all that monkey business you're doing with fseek is done inside this
   // function copying memory to memory. No file IO operations in here.
   transformCubeXYZ_to_ZYX( cubeXYZ, cubeZYX, sizeOfCubeXYZ );

   // one big fat very fast fwrite. Optimal use of file io cache.
   fwrite(  file, cubeZYX, 1, sizeOfCubeXYZ );

   free( cubeZYX ); // quiet pedantry.
}

@edit2:

好的,假设您不能在内存中全部转换它,然后在平面中转换它并一次写出一个平面 - 按文件顺序 - 没有 fseeks。

假设一个 [XYZ] 立方体在内存中布置为一系列 Z [XY] 矩阵。那就是你的立方体的 [XY] 平面在内存中是连续的。你想写成[ZYX]。因此,您要在文件中写出一系列 X [ZY] 矩阵。每个 [ZY] 在文件中都是连续的。

所以你做这样的事情:

void writeCubeZYX( int* cubeXYZ, int x, int y, int z, FILE* file )
{
   int sizeOfPlaneZY = sizeof( int ) * y * z; 
   int* planeZY = malloc( sizeOfPlaneZY );

   for ( int i = 0; i < X; i++ )
   {
      // all that monkey business you're doing with fseek is done inside this
      // function extracting one ZY plane at a time. No file IO operations in here.
      extractZYPlane_form_CubeXYZ( cubeXYZ, planeZY, i );

      // in X big fat very fast fwrites. Near optimal use of file io cache.
      fwrite(  file, planeZY, 1, sizeOfPlaneZY );
   } 

   free( planeZY ); // quiet pedantry.
}    
于 2012-08-09T00:48:12.760 回答
1

如果你正在做大量的随机访问写作。我建议你使用 mmap。mmap 将内存页面映射到您的文件,它由操作系统控制。类似于内存交换机制。

另一种方法是您可以使用异步 IO。它由 GLIBC http://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html提供

它只是将数据放入内存中的队列中,然后创建另一个线程来管理 IO。

于 2014-08-20T06:29:29.687 回答
0

如果您不介意磁盘上的文件是压缩文件,那么在写入时压缩它可能会更快。这加快了速度,因为瓶颈通常是将字节写入磁盘,并且通过在写入时进行压缩,可以减少需要写入的字节数。

这当然取决于您的数据是否适合压缩。在 c++ 中压缩输出的一种选择是 gzip。例如:我如何读取/写入 gzip 压缩文件?

但是在您的情况下,这可能不适用-您的问题尚不清楚您何时/为什么要寻找。您预期的写入模式是什么?

于 2012-08-09T00:45:47.030 回答