ファイルへの書き込み性能 – プログラミング – Home

ファイルへの書き込み性能
 
通知
すべてクリア

[解決済] ファイルへの書き込み性能


パズ
 パズ
(@パズ)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

こんにちは。いつも参考にさせていただいております。
Win2K SP4 VC++6 SP5 で開発をしております。

ファイル書き込みに関して、もやもやしており質問させてください。

Win32SDKのCreateFileで1つのファイルを生成します。
このファイルに対して、
WriteFile、FlushFileBuffersで書き込みをかける場合と、
CreateFileMapping、MapViewOfFileで仮想メモリ化した上で
書き込みをかける場合のどちらが通常選ばれるものでしょうか?
ファイルの最大サイズとしては8MB程度を想定しています。

このファイルには1プロセスからしかアクセスしない決まりがあり、
プロセス間通信に使用するものではありません。
また、ファイルハンドルへのアクセス時には、
スレッド間の排他にクリティカルセクションを使用します。

仮想メモリ化するとあらかじめ指定のサイズでファイルが
作成されるため、WriteFileを使用する場合にくらべ
ハーディディスクへの書き込み時間が早いなどの理由が
あれば仮想メモリのほうが良い気がするのですが、
Pen4 3.2Ghz、メモリ1GBの環境ですと、
スレッドを1000個ほど立ち上げて同時に書き込んだとしても
ほとんど性能に差はありません。

皆様よろしくお願いします。


引用未解決
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

どういう手順でファイルを作るにせよ、
本当にディスクメディア上にファイルを作るのであれば (メモリ上の擬似ファイルでなく)
律速となるのはディスク自体の速度でしょう。
差が出なくて当然なような気がします。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

質問の意味が分りません。
「CreateFileMapping」を使ってなにをしたいのかが分りません。

>Win32SDKのCreateFileで1つのファイルを生成します。
をした後で、「CreateFileMapping」や「MapViewOfFile」を行っても
何も変わらないと思います。

パズさんが実際に行いたいことを示して下さい。


返信引用
パズ
 パズ
(@パズ)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

tetrapodさん、ITOさん、ご返答ありがとうございます。

分かりにくい質問をしてしまって申し訳ありません。

私が「CreateFileMapping」について理解が足りないのかもしれません。
私はこれまで、「CreateFileMapping」は異なるプロセス間で
データ共有に使用するものだと認識しています。

ですが、他人が書いたソースを読む機会があり、
1プロセスからしかアクセスしないファイルへの書き込みを行う際に
性能を考慮して「CreateFileMapping」を使用するとのコメントが
あったため、「え、早くなるの?」と思った次第です。

。。。変わらないようですね。
ありがとうございました。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>私はこれまで、「CreateFileMapping」は異なるプロセス間で
>データ共有に使用するものだと認識しています。
会っていると思います。

「CreateFileMapping」でファイルへの書き込みが早くなるのは、
「CreateFileMapping」で作成したメモリー領域をファイルの
データ領域に使うからだと認識しています。
#間違っていたらフォロ-お願いします。

もちろん、メモリーに書いたデータは最後ディスクに書かなければならないです。
僕は、MFCの「CMemFile」を使ったことがあります。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

訂正します。
>会っていると思います。 誤

正 それで正しいと思います。


返信引用
超初心者
 超初心者
(@超初心者)
ゲスト
結合: 23年前
投稿: 139
 

実際に測定したわけじゃないので間違えているかもしれません。

毎回アクセスしたい位置をif文で判断して
今まで使用していたバッファを保存したり
次のデータをバッファへ読み込みしたりしますよね。

これに対し
メモリ不足のときにページアウトする機能を利用して保存とする。
また確保していないアドレスの読み込みをすると
ページフォルト例外が起きてページインを行うのを読み込みとする。

if文がいらなくなる。←速くなる
読み書きのコードも書かなくていい。←OSの仮想メモリの機能だから効率のいいコード
だろう。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

fwrite で CRTL 経由しようが
WriteFile で CRTL をバイパスして OS を直呼びしようが
*p=a; として OS のページ例外を使おうが
ボトルネックな場所で速度は決まり、それは現状ディスク装置です。
# i-RAM とか使えば S-ATA の転送速度になるでしょうけど

「効率のいい」「性能を考慮」の文言の意図次第ですな。
自作ソフトのサイズ=効率であるなら *p=a; が一番効率がイイ。
アプリケーション上の命令語は mov 命令1個になるわけだし。


返信引用
超初心者
 超初心者
(@超初心者)
ゲスト
結合: 23年前
投稿: 139
 

以下の順だった。
(1)メモリマップトファイル
(2)適当なサイズのバッファを使う
(3)ファイルサイズと同じサイズのバッファを使う

(2)は、
1MBとか適当なサイズのバッファを用意して、
毎回アクセスしたい位置をif文で判断して
今まで使用していたバッファを保存したり
次のデータをバッファへ読み込みしたりする。

(3)は、
ファイルサイズと同じサイズのバッファを用意して、
読み書きは一度だけ。

(3)はサイズが大きいほど(2)より遅くなる。

スラッシングが起きればどの方法も遅い(念のため)。

(念のため)メモリマップトファイルを良く知らないので間違えているかもしれませ
ん。
予めサイズ指定することでHDDの何処にページインアウトするか予約済みなので敏速だと
思う。
サイズ制限があるから使えない用途があるのが残念だ。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

CreateFileMappingの使い方は、

(1) 8MB?の領域を確保する。
(2) 「CreateFile」を行う。
(3) 「CreateFileMapping」で「CreateFile」のハンドルから、
  MapHandleを得る。
(4) 「MapViewOfFile」の戻り値で、確保した領域を指定する。
(5) 確保した領域に変更を加える。
(6) 「UnmapViewOfFile」で変更結果がファイルに反映される。
(7) 「CloseHandle」

まだ、やったことはないですが、このような作業になるようです。

  


返信引用
パズ
 パズ
(@パズ)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

みなさま、ご無沙汰してしまって申し訳ありません。

>(1) 8MB?の領域を確保する。
>(2) 「CreateFile」を行う。
>(3) 「CreateFileMapping」で「CreateFile」のハンドルから、
>  MapHandleを得る。
>(4) 「MapViewOfFile」の戻り値で、確保した領域を指定する。
>(5) 確保した領域に変更を加える。
>(6) 「UnmapViewOfFile」で変更結果がファイルに反映される。
>(7) 「CloseHandle」

この手順を前提に質問していました。
説明が悪すぎたようで申し訳ありません。。

(5)のところで何度もファイルに書き込みを行う場合、
・上記の手順でファイルに書き込む場合
 (プログラムの最初で(4)まで行っておき、プログラム終了時に
  (7)でファイルハンドルと「CreateFileMapping」した
  ハンドルを閉じる)
・(2)でCreateFileしたハンドルに対してWriteFileで書きこむ場合

とで、一般的にどちらが選ばれるものでしょうか?
ということを質問したつもりでした。

性能に関しては、tetrapodさんがおっしゃるように、
結局HDDがボトルネックになるのだから、
結果的に変わらないのだろうと理解しました。

ただし、超初心者さんがおっしゃるように、
「CreateFileMapping」のほうはあらかじめ領域固定でスワップ領域が
確定しているので、WriteFileで書き込むたびにファイルサイズがすこしずつ
増加していくよりも早いのではないか。

と理解しました。

皆様ありがとうございました。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

「CreateFileMapping」、「MapViewOfFile」、「UnmapViewOfFile」は、
WriteFileやReadFileを使いません。
「MapViewOfFile」で指定されたメモリ空間を直接書換えます。
「MapViewOfFile」を実行したときファイルの内容は、メモリー空間にすべて
読み込まれます。
「UnmapViewOfFile」により、メモリー空間の内容がファイルに書込まれます。
「CreateFileMapping」、「MapViewOfFile」、「UnmapViewOfFile」の使用条件は、
指定したメモリ空間 = ファイルの容量です。

今回調べてみましたが、以上の内容でした。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

ファイルの書込み・読込みをファイルでなくメモリーに対して
おこないたいのであれば、「CMemFile」を使うのがいいと思います。
MFCの関数です。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました