• Save
N3495 inplace realloc
Upcoming SlideShare
Loading in...5
×
 

N3495 inplace realloc

on

  • 249 views

A presentation about inplace realloc at C++14 Study meeting in Japan.

A presentation about inplace realloc at C++14 Study meeting in Japan.

Statistics

Views

Total Views
249
Views on SlideShare
249
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    N3495 inplace realloc N3495 inplace realloc Presentation Transcript

    • N3495 inplace realloc 2013/12/14 13:30 to 18:00 に開催された、C++14勉強会 http://atnd.org/events/45289 での発表内容に、その後のフォローアップ内容を追記 SC22WG21 エキスパート 近藤 貴俊 (株式会社 オージス総研) 2014/1/30 1
    • N3495 提案概要 • 提案者 – Ariane van der Steldt ariane@stack.nl • 提案日 – 2012-12-07 • std::allocator_traits にC言語のreallocのよう に アロケート済みメモリのリサイズが可能 な インターフェースを追加しようという提 案 2014/1/30 2
    • N3495 IV 提案インターフェース 2014/1/30 template<typename Alloc> class std::allocator_traits { public: リサイズしたいメモリのポインタ ... /* Existing definition. */ static pointer alloc_resize(Alloc& a, pointer p, size_type n_cur, size_type n_new) { 現在の(変更前の)サイズ 変更後のサイズ /* * p, having n_cur elements, reallocのようにメモリの移動は行わない * would change to having n_new elements. * If the allocator does not support this, * std::bad_alloc() is thrown. 要素を増やすことができない場合は、 std::bad_alloc()をthrow * * (p, n_cur) must refer to a previous allocation, * or the behaviour is undefined. 前回の確保に対応していないのを渡したら * undefined behavior * This function is implemented as: * a.alloc_resize(p, n_cur, n_new) iff implemented by Alloc, * or as * throw std::bad_alloc() otherwise. */ return p; 実装されていない場合はstd::bad_alloc()をthrow } }; 3
    • IV N3495 標準ライブラリの変更 • 全ての連続したストレージを持つコンテ ナにおいて、allocateしてからmoveする箇 所があればその前に、alloc_resizeの処理を 追加する。 2014/1/30 4
    • V N3495 失敗時にbad_allocを返すことについて • mis-useの可能性を最小化する – 例外なので戻り値チェック漏れがない • アロケータの実装とメモリの使用状況に よるが、極めて頻繁に例外発生パスを通 過し得る 2014/1/30 5
    • V N3495 この機能の追加について • マイクロソフトがheapの実装で類似の機能を 用いている • reallocの、メモリの移動が発生しない場合の 挙動と同じsemanticsである • O(n)の操作をO(1)にできる • アロケータがresize_allocを提供しない場合、 bad_alloc()をthrowするため、追加の機能が必要と コンテナでそれをcatchしてallocate - move する処理のことだと思われる なる しかし、良いコンパイラはinline展開を行い、 さらに、このthrowとcatchを取り除く最適化を行う だ try { throw std::bad_alloc(); } catch (std::bad_alloc const&) が無くなるということか? ろう。 inline展開 光成さんの指摘、および、その後のML議論で、そのような最適化は現在行われていないことを確認 2014/1/30 https://groups.google.com/a/isocpp.org/forum/#!searchin/std-proposals/inplace/std-proposals/enjN4nBon4M/RIl4Rgh5bakJ 6
    • V N3495 この機能の追加について • Actually a big counter-argument, which I suspect is the cause for this not being in the c++11 standard in the first place: – CON: exact semantics not supported by the C standard, nor in new[]/delete[] operators, making an implementation for std::allocator hard. • C標準では、このsemacticsがサポートされていない reallocで、メモリアドレスそのままで伸長できない場合、メモリの移動が発生してしま う • new[], delete[] でもリサイズはできない • std::allocatorの実装が大変である 伸長できないとき、null ポインタを返すような、resizeみたいなものがあればいいのかな 後ほど、深掘りして議論する 2014/1/30 7
    • N3495 V 【参考】libsupc++ new_op.cc の実装 using std::new_handler; using std::bad_alloc; #if _GLIBCXX_HOSTED using std::malloc; #else // A freestanding C runtime may not provide "malloc" -- but there is no // other reasonable way to implement "operator new". extern "C" void *malloc (std::size_t); #endif _GLIBCXX_WEAK_DEFINITION void * operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc) { void *p; /* malloc (0) is unpredictable; avoid it. */ if (sz == 0) sz = 1; p = (void *) malloc (sz); while (p == 0) { new_handler handler = std::get_new_handler (); if (! handler) _GLIBCXX_THROW_OR_ABORT(bad_alloc()); handler (); p = (void *) malloc (sz); } return p; } 2014/1/30 8
    • V N3495 名前候補 • realloc – Cのライブラリ関数と同名で異なるセマンティックス のため却下 • realloc_inplace – 同上 • reallocate_inplace – 名前が長すぎるので却下 • alloc_resize – existing allocationをresizeするのでOK 振る舞いが提案の主題で、名前は2の次。良い名前Welcome 2014/1/30 9
    • N3495 V.1 サイズ拡張の成功率向上要因 • ASLR(Address Space Layout Randomization) – 今時の多くのアロケータは、ASLRを用いてい る – この結果、アロケートされたメモリブロック 間に 「2つの並行して行われる」というのは、あまり関係ない気がする 隙間が生じやすい • メモリの解放 – 2つの並行して行われるメモリアロケーション において、確保済みメモリが解放されること で、隙間が生じたり、拡がったりする。 2014/1/30 10
    • N3495 std::allocatorでalloc_resizeを実装 • Cとは全く別のアロケータ – Cとの共存時、効率が悪いのでNG • リサイズ可能かどうかを調べる、try_realloc みたいな関数をどこかに追加 – reallocを呼ぶまでに状態が変わるのでNG • リサイズ可能ならリサイズし、そうでなければ、 nullポインタを返すresize みたいな関数を どこかに追加 – Cのreallocの前半処理みたいなイメージ – よさげ? 2014/1/30 11
    • N3495 resizeをどこに追加する? • C標準ライブラリ – Cの規格改定に合わせて提案が必要 – Cユーザにメリットがあるか、不明 • C++では、move時にmemcpyでは困るという強い動機がある。 • C++標準ライブラリ 今回追加 – malloc, free, realloc との整合性が気になる 宣言済み – namespace std { using malloc; using free; using realloc; resizeの定義; } – resizeの実装を行うためには、C標準ライブラリの内部実装 (freelistとか)の知識が必要。同期してUpdateするなどメンテも必要。 • g++, clang++, VC++など全てCと合わせてリリースしているので問題は少ない? – C++規格で、resizeの説明を記述するのが、大変そう • mallocとかの詳細はC規格参照としつつ書けるかどうか。。。 2014/1/30 12
    • N3495 誤り指摘 • VI: Technical specifications XXX not the actual wording in the final standard, mostly intended to illustrate the proposed semantics. std::allocator may or may not implement std::allocator<T>::alloc_resize(pointer p, size_type n_cur, size_type n_new). If the combination (p, n_cur) does not reflect an existing allocation, an std::invalid_argument exception will be thrown. undefined behaviorの誤りだと思われる。 2014/1/30 13