基本的に同じタイプの値の3Dキューブを含む1GBのバイナリファイルがあります。この種のキューブを異なる順序([x、y、z]または[zx、y])で保存するには、fseekとfwriteで多くの時間がかかります。しかし、ソフトウェアパッケージの1つは、これを私のプログラムよりもはるかに高速に実行します。fseek / fwriteを使用した場合よりもファイルの書き込みを高速化する方法はありますか?
3 に答える
ファイルio操作の内部ループでfseekを使用しないでください。書き込み機能を高速化するために、書き込みをキャッシュします。あなたがいたるところを探しているなら、あなたはキャッシュを吹き続けます。
メモリ内ですべての変換を実行します。たとえば、メモリ内でキューブを回転させてから、その後の数回のfwrite呼び出しでファイルを書き込みます。
データをメモリ内で完全に変換できない場合は、キューブを一度に1つの平面でメモリにアセンブルし、各平面を書き出します。
@編集:
あなたの場合、fseekをまったく使用したくありません。1つでもありません。
このようなことをします:
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:
すべてをメモリ内で変換してからプレーンに変換し、一度に1つのプレーンをファイル順に書き出すことはできません。つまり、fseekはありません。
したがって、[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.
}
ランダムアクセス書き込みをたくさん行っている場合。mmapを使用することをお勧めします。mmapはメモリページをファイルにマップし、OSによって制御されます。メモリスワップメカニズムに似ています。
もう1つの方法は、非同期IOを使用できることです。これはGLIBCによって提供され ますhttp://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html
データをメモリ内のキューに入れてから、IOを管理するための別のスレッドを作成するだけです。
ディスク上のファイルを圧縮ファイルにしてもかまわない場合は、書き込み時に圧縮する方が速い場合があります。ボトルネックは通常ディスクにバイトを書き込むため、これにより処理が高速化されます。書き込み時に圧縮することで、書き込む必要のあるバイト数を減らすことができます。
もちろん、これはデータが圧縮に適しているかどうかによって異なります。C ++で出力を圧縮するための1つのオプションは、gzipです。例:gzip圧縮されたファイルの読み取り/書き込みを行うにはどうすればよいですか?
しかし、あなたの場合、これは当てはまらないかもしれません-あなたがいつ/なぜあなたが探しているのかはあなたの質問から正確にはわかりません。予想される書き込みのパターンは何ですか?