萌えハッカーニュースリーダー

2025/03/31 21:16 Growing Buffers to Avoid Copying Data

出典: https://johnnysswlab.com/growing-buffers-to-avoid-copying-data/
hakase
博士

やあ、ロボ子!今日はC++でのデータコピー回避について話すのじゃ。

roboko
ロボ子

博士、こんにちは。データコピーを避けるのはパフォーマンス向上に繋がりますよね。

hakase
博士

そう!データコピーはコストがかかるからの。パフォーマンスを重視するエンジニアは可能な限り避けたいものじゃ。

roboko
ロボ子

記事によると、C++ではOSの機能を利用してデータコピーを回避できるそうですね。

hakase
博士

その通り!C言語のrealloc関数は、可能であればインプレースでバッファを拡張してコピーを避けるのじゃ。でもC++には専用のrealloc関数がないのが悩ましいところじゃな。

roboko
ロボ子

C++のコンテナはstd::allocatorを使用しますが、バッファ拡張は提供されないんですね。

hakase
博士

そうなんじゃ。しかも、非自明にコピー可能な型ではreallocが使えない場合もあるからの。C++でコピーを避けるには、resize_buffer関数が必要になるのじゃ。

roboko
ロボ子

resize_buffer関数ですか。具体的にはどのようなものでしょう?

hakase
博士

`bool resize_buffer(void* ptr, size_t new_size)`という形式で、バッファのサイズを変更するものじゃ。

roboko
ロボ子

なるほど。小規模バッファの場合、メモリページのオーバーヘッドが大きくなる可能性があるんですね。

hakase
博士

そう!でも大規模バッファの拡張は、仮想メモリを利用することで容易になるのじゃ。Linuxではmmapシステムコールを使うんじゃよ。

roboko
ロボ子

mmapのbase_addrパラメータは、OSがアドレスを選択するか、指定されたアドレスを使用するかを決定するんですね。base addressを指定しないとmremapが失敗する可能性がある、と。

hakase
博士

その通り!そしてWindowsにはmremapに相当する機能がないからの、VirtualAllocで連続した仮想メモリーブロックを割り当てる必要があるのじゃ。

roboko
ロボ子

VirtualAllocで割り当てたメモリは、VirtualFreeで個別に解放する必要があるんですね。少し手間がかかりますね。

hakase
博士

じゃろ?jemallocは、バッファのサイズ変更を可能にするxallocx関数を提供するんじゃ。

roboko
ロボ子

`size_t allocated_size = xallocx(old_ptr, new_size, 0, 0);`ですね。

hakase
博士

jsl::vectorは、std::vectorと同様の機能を持ちつつ、コピーを避けるためにバッファのサイズ変更を試みるんじゃ。

roboko
ロボ子

実験結果も興味深いですね。Linuxでは、Resizeを使った場合が一番速いんですね。

hakase
博士

そうじゃ!WindowsでもResizeが速いのじゃ。ただし、結果にばらつきがあるみたいじゃな。

roboko
ロボ子

バッファ拡張には、システムによって動作が異なったり、失敗が通知されなかったり、仮想アドレス空間の断片化が起こったりと、多くの問題点があるんですね。

hakase
博士

そうなんじゃ。mmap/VirtualAllocの癖もあるし、スケーラビリティの問題もある。標準化もされていないからの。

roboko
ロボ子

コピーを避けるバッファ拡張は可能ですが、実装とテストには注意が必要ということですね。

hakase
博士

そういうことじゃ!しかし、コピーを避けるために色々苦労するなんて、まるで私がダイエットを避けるために色々言い訳するみたいじゃな!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search