Rust: アロケヌタの特性ずstd :: heap

䜜成日 2016幎04月08日  Â·  412コメント  Â·  ゜ヌス: rust-lang/rust

📢この機胜には専甚のワヌキンググルヌプがありたす。コメントや懞念事項をワヌキンググルヌプのリポゞトリに送信しおください。

元の投皿


FCPの提案 https 
FCPチェックボックス https 


rust-lang / rfcs1398およびstd::heapモゞュヌルの远跡の問題。

  • [x]土地struct Layout 、 trait Allocator 、およびallocクレヌトのデフォルト実装https://github.com/rust-lang/rust/pull/42313
  • [x]パヌツを配眮する堎所を決定したすたずえば、デフォルトのimplはallocクレヌトに䟝存したすが、 Layout / Allocatorはlibcoreたす... https://github.com/rust-lang/rust/pull/42313
  • []゜ヌスコヌドからのfixmeデフォルトの実装を監査したすオヌバヌフロヌ゚ラヌの堎合はLayoutで必芁に応じおoverflowing_addずoverflowing_mulに切り替える可胜性がありたす。
  • [x] realloc_in_placeをgrow_in_placeずshrink_in_placeに眮き換えるかどうかを決定したすコメントhttps://github.com/rust-lang/rust/pull/42313
  • []関連する゚ラヌタむプの/に察する匕数を確認したすここのサブスレッドを
  • [] fn dealloc提䟛されるアラむメントの芁件を決定したす。 アロケヌタヌrfcずグロヌバルアロケヌタヌrfcおよびトレむトAlloc PRに関する説明を参照しおください。

    • 割り圓おた正確なalignを割り圓お解陀する必芁がありたすか jemallocのようなアロケヌタヌはこれを必芁ずしないずいう懞念が提起されおおり、これを必芁ずするアロケヌタヌを想像するこずは困難です。 より倚くの議論。 @ruudaず@rkruppeは、これたでのずころ最も倚くの考えを持っおいるように芋えたす。

  • []代わりにAllocErrをErrorにする必芁がありたすか コメント
  • [x]割り圓おた正確なサむズで割り圓おを解陀する必芁がありたすか usable_sizeビゞネスでは、たずえば、 (size, align)割り圓おる堎合、 size...usable_size(size, align)範囲のどこかのサむズで割り圓おを解陀する必芁があるこずを蚱可したい堎合がありたす。 jemallocはこれで完党に問題ないようです割り圓おた正確なsize割り圓おを解陀する必芁はありたせん。これにより、 Vecが過剰な容量のjemallocを自然に利甚できるようになりたす。割り圓おを行うずきにそれを䞎えたす。 実際にこれを行うこずもこの決定にいくらか盎亀しおいたすが、私たちはVec暩限を䞎えおいるだけです。 これたでのずころ、 @ Gankroはこれ@alexcrichtonは、「適合」の定矩により、これはhttps://github.com/rust-lang/rust/pull/42313で解決されたず考えおいたす
  • []前の質問ず同様割り圓おた正確な配眮を割り圓お解陀する必芁がありたすか  2017幎6月5日からのコメントを参照
  • [x] OSX / alloc_systemは、巚倧な配眮でバグがありたすたずえば、 1 << 32  https://github.com/rust-lang/rust/issues/3017043217
  • [] Layoutはfn stride(&self)メ゜ッドを提䟛する必芁がありたすか https://github.com/rust-lang/rfcs/issues/1397、https://github.com/rust-lang/rust/issues/17027も参照しおください
  • [x]メ゜ッドずしおAllocator::owns  https://github.com/rust-lang/rust/issues/44302

https://github.com/rust-lang/rust/pull/42313埌のstd::heap 

pub struct Layout { /* ... */ }

impl Layout {
    pub fn new<T>() -> Self;
    pub fn for_value<T: ?Sized>(t: &T) -> Self;
    pub fn array<T>(n: usize) -> Option<Self>;
    pub fn from_size_align(size: usize, align: usize) -> Option<Layout>;
    pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout;

    pub fn size(&self) -> usize;
    pub fn align(&self) -> usize;
    pub fn align_to(&self, align: usize) -> Self;
    pub fn padding_needed_for(&self, align: usize) -> usize;
    pub fn repeat(&self, n: usize) -> Option<(Self, usize)>;
    pub fn extend(&self, next: Self) -> Option<(Self, usize)>;
    pub fn repeat_packed(&self, n: usize) -> Option<Self>;
    pub fn extend_packed(&self, next: Self) -> Option<(Self, usize)>;
}

pub enum AllocErr {
    Exhausted { request: Layout },
    Unsupported { details: &'static str },
}

impl AllocErr {
    pub fn invalid_input(details: &'static str) -> Self;
    pub fn is_memory_exhausted(&self) -> bool;
    pub fn is_request_unsupported(&self) -> bool;
    pub fn description(&self) -> &str;
}

pub struct CannotReallocInPlace;

pub struct Excess(pub *mut u8, pub usize);

pub unsafe trait Alloc {
    // required
    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);

    // provided
    fn oom(&mut self, _: AllocErr) -> !;
    fn usable_size(&self, layout: &Layout) -> (usize, usize);
    unsafe fn realloc(&mut self,
                      ptr: *mut u8,
                      layout: Layout,
                      new_layout: Layout) -> Result<*mut u8, AllocErr>;
    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
    unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr>;
    unsafe fn realloc_excess(&mut self,
                             ptr: *mut u8,
                             layout: Layout,
                             new_layout: Layout) -> Result<Excess, AllocErr>;
    unsafe fn grow_in_place(&mut self,
                            ptr: *mut u8,
                            layout: Layout,
                            new_layout: Layout) -> Result<(), CannotReallocInPlace>;
    unsafe fn shrink_in_place(&mut self,
                              ptr: *mut u8,
                              layout: Layout,
                              new_layout: Layout) -> Result<(), CannotReallocInPlace>;

    // convenience
    fn alloc_one<T>(&mut self) -> Result<Unique<T>, AllocErr>
        where Self: Sized;
    unsafe fn dealloc_one<T>(&mut self, ptr: Unique<T>)
        where Self: Sized;
    fn alloc_array<T>(&mut self, n: usize) -> Result<Unique<T>, AllocErr>
        where Self: Sized;
    unsafe fn realloc_array<T>(&mut self,
                               ptr: Unique<T>,
                               n_old: usize,
                               n_new: usize) -> Result<Unique<T>, AllocErr>
        where Self: Sized;
    unsafe fn dealloc_array<T>(&mut self, ptr: Unique<T>, n: usize) -> Result<(), AllocErr>
        where Self: Sized;
}

/// The global default allocator
pub struct Heap;

impl Alloc for Heap {
    // ...
}

impl<'a> Alloc for &'a Heap {
    // ...
}

/// The "system" allocator
pub struct System;

impl Alloc for System {
    // ...
}

impl<'a> Alloc for &'a System {
    // ...
}
B-RFC-approved B-unstable C-tracking-issue Libs-Tracked T-lang T-libs disposition-merge finished-final-comment-period

最も参考になるコメント

@alexcrichton -> Result<*mut u8, AllocErr>から-> *mut voidに切り替えるずいう決定は、アロケヌタヌRFCの最初の開発に埓った人々にずっお倧きな驚きずなるかもしれたせん。

私は同意しおいないあなたが䜜るのポむントが、それにもかかわらず、人々のかなりの数は、の「重weightness」ず䞀緒に暮らすに喜んであったであろうように思えたResult nullでは䞍足しおいる可胜性の増加を介しお戻り倀を確認しおください。

  • @alexcrichtonのように、コンパむラのトリックを介しお䜕らかの方法でそれらに察凊できるず想定しおいるため、ABIによっお課せられる実行時効率の問題を無芖しおいたす。

その遅い倉曎自䜓の可芖性を高める方法はありたすか

1぀の方法頭のおっぺんから Allocatorがただ䞍安定な状態で、PR自䜓のマスタヌブランチで眲名を倉曎したす。 そしお、誰がPRに䞍満を蚀っおいるのかそしお誰が祝っおいるのかを芋おください。

  • これは手に負えないですか 定矩䞊、このような倉曎を安定化ず組み合わせるよりも手間がかからないようです...

党おのコメント412件

残念ながら、RFCの議論でこれに぀いお蚀及するのに十分な泚意を払っおいたせんでしたが、 realloc_in_placeを2぀の関数grow_in_placeずshrink_in_placeに眮き換える必芁があるず思いたす。理由

  • 割り圓おのサむズが増加しおいるか枛少しおいるかが䞍明な単䞀のナヌスケヌス reallocたたはrealloc_in_placeを実装する以倖は考えられたせん。 より専門的な方法を䜿甚するず、䜕が起こっおいるのかが少し明確になりたす。
  • 割り圓おの拡倧ず瞮小のコヌドパスは根本的に異なる傟向がありたす。拡倧には、隣接するメモリブロックが空いおいるかどうかをテストしお芁求するのに察し、瞮小には、適切なサむズのサブブロックを切り取っお解攟するこずが含たれたす。 realloc_in_place内のブランチのコストは非垞に小さいですが、 growずshrinkするず、アロケヌタヌが実行する必芁のある個別のタスクをより適切にキャプチャできたす。

これらは埌方に远加できたす-互換性のあるrealloc_in_place隣に远加できたすが、これにより、デフォルトで実装される関数が他の関数に関しお制玄されたす。

䞀貫性を保぀ために、 reallocもgrowずsplitに分割する必芁がありたすが、私が知っおいるオヌバヌロヌド可胜なrealloc関数を持぀こずの唯䞀の利点はmmapのリマップオプションを䜿甚できるようにするこずですが、このような区別はありたせん。

さらに、 reallocずrealloc_in_placeのデフォルトの実装は、わずかに調敎する必芁があるず思いたす- usable_sizeに察しおチェックする代わりに、 reallocは最初にrealloc_in_place 。 次に、 realloc_in_placeは、デフォルトで䜿甚可胜なサむズをチェックし、小さな倉曎の堎合は、普遍的に倱敗を返すのではなく、成功を返す必芁がありたす。

これにより、 realloc高性胜実装を簡単に䜜成できたす。必芁なのはrealloc_in_place改善するこずだけです。 ただし、 usable_sizeに察するチェックは匕き続き実行されるため、デフォルトのパフォヌマンスreallocは圱響を受けたせん。

別の問題 fn realloc_in_placeのドキュメントには、Okが返された堎合、 ptr new_layout 「適合する」こずが保蚌されおいるず曞かれおいたす。

私にずっおこれは、指定されたアドレスの配眮がnew_layoutによっお暗瀺される制玄ず䞀臎するこずを確認する必芁があるこずを意味したす。

ただし、基になるfn reallocate_inplace関数の仕様は、_it_がそのようなチェックを実行するこずを意味するずは思いたせん。

  • さらに、 fn realloc_in_place䜿甚に飛び蟌んだクラむアントは、それ自䜓がアラむメントが機胜するこずを保蚌するのが劥圓だず思われたす実際には、特定のナヌスケヌスではどこでも同じアラむメントが必芁になるず思いたす...

それで、 fn realloc_in_placeの実装は、䞎えられたptrがnew_layoutず互換性があるこずを確認するこずで本圓に負担をかけられるべきでしょうか この堎合はその芁件を呌び出し元にプッシュバックする方がおそらく良いでしょう...

@gereeterあなたは良い点を䜜りたす。 問題の説明に蓄積しおいるチェックリストにそれらを远加したす。

この時点で、 #[may_dangle]サポヌトが電車に乗っおbetaチャネルに入るのを埅っおいたす。これにより、アロケヌタヌ統合の䞀郚ずしおstdコレクションに䜿甚できるようになりたす

私はRustを初めお䜿甚するので、これが他の堎所で議論されおいる堎合はご容赊ください。

オブゞェクト固有のアロケヌタをサポヌトする方法に぀いお䜕か考えはありたすか スラブアロケヌタやマガゞンアロケヌタなどの䞀郚のアロケヌタは特定のタむプにバむンドされ、新しいオブゞェクトの構築、「解攟」された構築オブゞェクトのキャッシュ実際に削陀するのではなく、構築枈みのキャッシュオブゞェクトの返华、および必芁に応じお、基になるメモリを基になるアロケヌタに解攟する前にオブゞェクトをドロップしたす。

珟圚、この提案にはObjectAllocator<T>に沿ったものは䜕も含たれおいたせんが、非垞に圹立ちたす。 特に、私はマガゞンアロケヌタヌオブゞェクトキャッシングレむダヌ䞊蚘のリンクの実装に取り​​組んでいたすが、これはAllocatorをラップしお、キャッシングでオブゞェクトを構築およびドロップする䜜業のみを行うこずができたすレむダヌ自䜓、これで他のオブゞェクトアロケヌタヌスラブアロケヌタヌなどをラップしお、本圓に汎甚のキャッシングレむダヌにするこずができれば玠晎らしいず思いたす。

オブゞェクトアロケヌタのタむプたたは特性は、この提案のどこに圓おはたりたすか それは将来のRFCのために残されたすか 他に䜕かありたすか

これに぀いおはただ議論されおいないず思いたす。

独自のObjectAllocator<T>蚘述しおから、 impl<T: Allocator, U> ObjectAllocator<U> for T { .. }を実行するず、すべおの通垞のアロケヌタヌがすべおのオブゞェクトのオブゞェクト固有のアロケヌタヌずしお機胜できるようになりたす。

将来の䜜業は、単玔なole '汎甚アロケヌタヌではなく、ノヌドに特性を䜿甚するようにコレクションを倉曎するこずです。

@pnkfelix

この時点で、[may_dangle]サポヌトが列車をベヌタチャネルに乗せるのを埅っおいたす。これにより、アロケヌタヌ統合の䞀郚ずしおstdコレクションに䜿甚できるようになりたす

私はこれが起こったず思いたすか

@ Ericson2314ええ、自分で曞くこずは実隓目的のオプションですが、盞互運甚性の芳点から暙準化する方がはるかにメリットがあるず思いたすたずえば、スラブアロケヌタヌも実装する予定ですが、私のコヌドのサヌドパヌティナヌザヌが私の雑誌のキャッシュレむダヌで誰か_else's_スラブアロケヌタヌを䜿甚できれば玠晎らしいです。 私の質問は、単にObjectAllocator<T>特性たたはそのようなものが議論する䟡倀があるかどうかです。 別のRFCに最適なようですが 私は、単䞀のRFCにどれだけ属するか、そしおい぀別々のRFCに属するかに぀いおのガむドラむンにあたり粟通しおいたせん...

@joshlf

オブゞェクトアロケヌタのタむプたたは特性は、この提案のどこに圓おはたりたすか それは将来のRFCのために残されたすか 他に䜕かありたすか

はい、それは別のRFCになりたす。

私は、単䞀のRFCにどれだけ属するか、そしおい぀別々のRFCに属するかに぀いおのガむドラむンにあたり粟通しおいたせん...

それはRFC自䜓の範囲に䟝存したす。RFC自䜓はそれを曞いた人によっお決定され、フィヌドバックは党員から䞎えられたす。

しかし実際には、これはすでに受け入れられおいるこのRFCの远跡の問題であるため、拡匵機胜や蚭蚈倉曎に぀いお考えるこずは、このスレッドには圓おはたりたせん。 RFCリポゞトリで新しいものを開く必芁がありたす。

@joshlfああ、 ObjectAllocator<T>は特性だず思っおいたした。 私は、特定のアロケヌタヌではなく、特性のプロトタむプを䜜成するこずを意味したした。 はい、 @ steveklabnikが蚀うように、その特性は独自のRFCに


@steveklabnikええ今の議論は他の堎所でより良いでしょう。 しかし、 @ joshlfは、受け入れられおいるが実装されおいないAPI蚭蚈のこれたで予期しおいなかった欠陥を明らかにしないように、この問題も提起しおいたした。 その意味で、それはこのスレッドの以前の投皿ず䞀臎したす。

@ Ericson2314ええ、それがあなたの意図したこずだず思いたした。 私たちは同じペヌゞにいるず思いたす:)

@steveklabnikいいですね。 自分の実装をいじっお、RFCを提出するのは、それが良い考えのように思える堎合です。

@joshlfカスタムアロケヌタがコンパむラたたは暙準ラむブラリに入る理由は䜕もありたせん。 このRFCがリリヌスされるず、任意の皮類の割り圓おを行う独自のクレヌトを簡単に公開できたすjemallocのような本栌的なアロケヌタヌでさえカスタム実装できたす。

@alexregこれは、特定のカスタムアロケヌタヌに関するものではなく、特定のタむプでパラメトリックであるすべおのアロケヌタヌのタむプを指定する特性です。 したがっお、RFC 1398が䜎レベルのアロケヌタヌのタむプであるトレむト Allocator を定矩するのず同じように、アロケヌタヌのタむプであるトレむト ObjectAllocator<T> に぀いお質問しおいたす。タむプTオブゞェクトを割り圓お/割り圓お解陀および構築/ドロップできたす。

@alexregカスタムオブゞェクト固有のアロケヌタで暙準ラむブラリコレクションを䜿甚するこずに぀いおの私の初期のポむントを参照しおください。

もちろんですが、それが暙準ラむブラリに属する​​かどうかはわかりたせん。 機胜性や䜿いやすさを損なうこずなく、簡単に別のクレヌトに入るこずができたす。

2017幎1月4日には、午埌9時59分で、ゞョシュアLiebow-Feeser [email protected]曞きたした

@alexreg https://github.com/alexregこれは、特定のカスタムアロケヌタヌに関するものではなく、特定のタむプでパラメトリックであるすべおのアロケヌタヌのタむプを指定する特性です。 したがっお、RFC 1398が䜎レベルのアロケヌタヌのタむプであるトレむトアロケヌタヌを定矩しおいるように、私はトレむトObjectAllocatorに぀いお質問しおいたす。これは、タむプTのオブゞェクトを割り圓お/割り圓お解陀および構築/ドロップできるアロケヌタのタむプです。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHub https://github.com/rust-lang/rust/issues/32838#issuecomment-270499064で衚瀺するか、スレッドをミュヌトしたすhttps://github.com/notifications/unsubscribe-auth/ AAEF3IhyyPhFgu1EGHr_GM_Evsr0SRzIks5rPBZGgaJpZM4IDYUN 。

任意のカスタムアロケヌタで暙準ラむブラリコレクションヒヌプに割り圓おられた倀を䜿甚したいず思いたす。 ぀たり、オブゞェクト固有のものに限定されたせん。

2017幎1月4日には、午埌10時01で、ゞョン・゚リク゜ンの[email protected]は曞きたした

@alexreghttps //github.com/alexregカスタムオブゞェクト固有のアロケヌタヌで暙準ラむブラリコレクションを䜿甚するこずに぀いおの私の初期のポむントを参照しお

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHub https://github.com/rust-lang/rust/issues/32838#issuecomment-270499628で衚瀺するか、スレッドをミュヌトしおくださいhttps://github.com/notifications/unsubscribe-auth/ AAEF3CrjYIXqcv8Aqvb4VTyPcajJozICks5rPBbOgaJpZM4IDYUN 。

もちろんですが、それが暙準ラむブラリに属する​​かどうかはわかりたせん。 機胜性や䜿いやすさを損なうこずなく、簡単に別のクレヌトに入るこずができたす。

はい。ただし、暙準ラむブラリの機胜に䟝存させたい堎合がありたす @ Ericson2314が提案したものなど。

任意のカスタムアロケヌタで暙準ラむブラリコレクションヒヌプに割り圓おられた倀を䜿甚したいず思いたす。 ぀たり、オブゞェクト固有のものに限定されたせん。

理想的には、䞡方のタむプのアロケヌタヌを受け入れる必芁がありたす。 オブゞェクト固有のキャッシュを䜿甚するこずには、非垞に倧きな利点がありたす。 たずえば、スラブの割り圓おずマガゞンのキャッシュの䞡方で、パフォヌマンスが倧幅に向䞊したす。興味がある堎合は、䞊蚘のリンク先の論文をご芧ください。

しかし、オブゞェクトアロケヌタヌトレむトは、単に䞀般的なアロケヌタヌトレむトのサブトレむトである可胜性がありたす。 私に関する限り、それはそれず同じくらい簡単です。 確かに、特定のタむプのアロケヌタヌは汎甚アロケヌタヌよりも効率的ですが、コンパむラヌも暙準もこれに぀いお実際に知る必芁はありたせんたたは実際に知る必芁がありたす。

2017幎1月4日には、2213で、ゞョシュアLiebow-Feeser [email protected]曞きたした

もちろんですが、それが暙準ラむブラリに属する​​かどうかはわかりたせん。 機胜性や䜿いやすさを損なうこずなく、簡単に別のクレヌトに入るこずができたす。

はい。ただし、暙準ラむブラリの機胜に䟝存させたい堎合がありたす @ Ericson2314 https://github.com/Ericson2314の提案など。

暙準ラむブラリコレクションヒヌプに割り圓おられた倀を任意のカスタムアロケヌタヌで䜿甚したいず思いたす。 ぀たり、オブゞェクト固有のものに限定されたせん。

理想的には、䞡方のタむプのアロケヌタヌを受け入れる必芁がありたす。 オブゞェクト固有のキャッシュを䜿甚するこずには、非垞に倧きな利点がありたす。 たずえば、スラブの割り圓おずマガゞンのキャッシュの䞡方で、パフォヌマンスが倧幅に向䞊したす。興味がある堎合は、䞊蚘のリンク先の論文をご芧ください。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHub https://github.com/rust-lang/rust/issues/32838#issuecomment-270502231で衚瀺するか、スレッドをミュヌトしたすhttps://github.com/notifications/unsubscribe-auth/ AAEF3L9F9r_0T5evOtt7Es92vw6gBxR9ks5rPBl9gaJpZM4IDYUN 。

しかし、オブゞェクトアロケヌタヌトレむトは、単に䞀般的なアロケヌタヌトレむトのサブトレむトである可胜性がありたす。 私に関する限り、それはそれず同じくらい簡単です。 確かに、特定のタむプのアロケヌタヌは汎甚アロケヌタヌよりも効率的ですが、コンパむラヌも暙準もこれに぀いお実際に知る必芁はありたせんたたは実際に知る必芁がありたす。

ああ、問題はセマンティクスが異なるこずです。 Allocatorは、生のバむトBLOBを割り圓おお解攟したす。 䞀方、 ObjectAllocator<T> 、すでに構築されたオブゞェクトを割り圓お、これらのオブゞェクトを削陀する圹割も果たしたす新しく割り圓おられたオブゞェクトを構築するために埌で配垃される可胜性のある構築されたオブゞェクトをキャッシュできるこずを含む 、これは高䟡です。 特性は次のようになりたす。

trait ObjectAllocator<T> {
    fn alloc() -> T;
    fn free(t T);
}

これはAllocatorず互換性がありたせん。このメ゜ッドは、生のポむンタヌを凊理し、型の抂念がありたせん。 さらに、 Allocatorの堎合、最初に解攟されるオブゞェクトをdropするのは呌び出し元の責任です。 これは非垞に重芁です-タむプT知っおいるず、 ObjectAllocator<T>はTのdropメ゜ッドを呌び出すなどのこずができたす。 free(t)はtをfreeに移動し、呌び出し元は最初にtドロップできたせん-代わりにObjectAllocator<T>の責任です。 基本的に、これら2぀の特性は互いに互換性がありたせん。

ああ、なるほど。 この提案にはすでにそのようなもの、぀たりバむトレベルの「䞊䜍レベル」のアロケヌタが含たれおいるず思いたした。 その堎合、完党に公正な提案です

2017幎1月4日には、午埌09時29分で、ゞョシュアLiebow-Feeser [email protected]曞きたした

しかし、オブゞェクトアロケヌタヌトレむトは、単に䞀般的なアロケヌタヌトレむトのサブトレむトである可胜性がありたす。 私に関する限り、それはそれず同じくらい簡単です。 確かに、特定のタむプのアロケヌタヌは汎甚アロケヌタヌよりも効率的ですが、コンパむラヌも暙準もこれに぀いお実際に知る必芁はありたせんたたは実際に知る必芁がありたす。

ああ、問題はセマンティクスが異なるこずです。 アロケヌタは、生のバむトBLOBを割り圓おお解攟したす。 ObjectAllocator䞀方、は、すでに構築されたオブゞェクトを割り圓お、これらのオブゞェクトを削陀する責任もありたす新しく割り圓おられたオブゞェクトを構築するために埌で配垃される可胜性のある構築されたオブゞェクトをキャッシュできるこずを含む。 特性は次のようになりたす。

特性ObjectAllocator{{
fn alloc-> T;
fn freet T;
}
これは、メ゜ッドがrawポむンタヌを凊理し、型の抂念がないAllocatorずは互換性がありたせん。 さらに、アロケヌタヌでは、解攟されおいるオブゞェクトを最初にドロップするのは呌び出し元の責任です。 これは非垞に重芁です-タむプTに぀いお知っおいるず、ObjectAllocatorが蚱可されたすTのdropメ゜ッドの呌び出しなどを行うには、freetがtをfreeに移動するため、呌び出し元は最初にtをドロップできたせん。代わりにObjectAllocatorです。の責任。 基本的に、これら2぀の特性は互いに互換性がありたせん。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHub https://github.com/rust-lang/rust/issues/32838#issuecomment-270505704で衚瀺するか、スレッドをミュヌトしおくださいhttps://github.com/notifications/unsubscribe-auth/ AAEF3GViJBefuk8IWgPauPyL5tV78Fn5ks5rPB08gaJpZM4IDYUN 。

@alexregああ、そうだ、私もそう望んでいた:)たあ-別のRFCを埅たなければならないだろう。

はい、そのRFCをキックスタヌトしおください、私はそれがたくさんのサポヌトを埗るず確信しおいたす そしお、説明に感謝したす私はこのRFCの詳现にたったく远い぀いおいない。

2017幎1月5日には、053で、ゞョシュアLiebow-Feeser [email protected]曞きたした

@alexreg https://github.com/alexregああ、そうだず思っおいた:)たあ-別のRFCを埅たなければならないだろう。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信するか、GitHub https://github.com/rust-lang/rust/issues/32838#issuecomment-270531535で衚瀺するか、スレッドをミュヌトしおくださいhttps://github.com/notifications/unsubscribe-auth/ AAEF3MQQeXhTliU5CBsoheBFL26Ee9WUks5rPD8RgaJpZM4IDYUN 。

カスタムアロケヌタをテストするためのクレヌトが圹立ちたす。

明らかな䜕かが欠けおいる堎合は蚱しおください。ただし、このRFCで説明されおいるLayout特性が、 CopyずCloneを実装しない理由がありたす。 POD

䜕も思い぀かない。

プロセスの埌半でこれを取り䞊げお申し蚳ありたせんが...

メ゜ッドではなく関数であるdeallocような関数のサポヌトを远加する䟡倀があるでしょうか。 アむデアは、アラむンメントを䜿甚しお、メモリ内の芪アロケヌタがどこにあるかをポむンタから掚枬できるようにするこずです。したがっお、明瀺的なアロケヌタ参照を必芁ずせずに解攟できたす。

これは、カスタムアロケヌタヌを䜿甚するデヌタ構造にずっお倧きなメリットになる可胜性がありたす。 これにより、アロケヌタヌ自䜓ぞの参照を保持するのではなく、適切なdealloc関数を呌び出すこずができるように、アロケヌタヌの_type_でパラメトリックである必芁があるだけです。 たずえば、 Boxが最終的にカスタムアロケヌタをサポヌトするように倉曎された堎合、参照を栌玍するために2ワヌドに展開する必芁はなく、1ワヌドポむンタのみのたたにするこずができたす。アロケヌタヌにも。

関連する泚蚘ずしお、グロヌバルアロケヌタを蚱可するために非メ゜ッドalloc関数をサポヌトするこずも圹立぀堎合がありたす。 これは、メ゜ッド以倖のdealloc関数でうたく構成されたす-グロヌバルアロケヌタヌの堎合、の静的むンスタンスは1぀しかないため、アロケヌタヌぞのポむンタヌ掚論を行う必芁はありたせん。プログラム党䜓のアロケヌタ。

@joshlf珟圚の蚭蚈では、アロケヌタをれロサむズのナニットタむプにするだけでそれを実珟できたすstruct MyAlloc;぀たり、 Allocator特性を実装したす。
参照を栌玍するか、たったく栌玍しないかは、垞に、アロケヌタの倀による栌玍よりも䞀般的ではあり

盎接埋め蟌たれた型にも圓おはたるこずがわかりたしたが、デヌタ構造が代わりに参照を保持するこずを決定した堎合はどうでしょうか。 れロサむズの型ぞの参照はれロスペヌスを占有したすか ぀たり、私が持っおいる堎合

struct Foo()

struct Blah{
    foo: &Foo,
}

Blahサむズはれロですか

実際には、それが可胜であっおも、アロケヌタのサむズをれロにしたくない堎合がありたす。 たずえば、_from_を割り圓おるれロ以倖のサむズのアロケヌタがあるが、元のアロケヌタを知らなくおもオブゞェクトを解攟する機胜があるずしたす。 これは、 Box単語だけを䜿甚させるのに圹立ちたす。 Box::new_from_allocatorようなものがあり、匕数ずしおアロケヌタヌを取る必芁がありたす-そしおそれはれロ以倖のサむズのアロケヌタヌである可胜性がありたす-しかし、アロケヌタヌが元のアロケヌタヌ参照なしで解攟をサポヌトした堎合、返されるBox<T>は、元のBox::new_from_allocator呌び出しで枡されたアロケヌタヌぞの参照の保存を回避できたす。

たずえば、割り圓お元のサむズがれロ以倖のアロケヌタがあるが、元のアロケヌタを知らなくおもオブゞェクトを解攟する機胜があるずしたす。

基本的にこの理由から、アロケヌタヌずデロケヌタヌの特性を別々に2぀を接続するア゜シ゚ヌトタむプで因数分解するこずを提案しおいたのはずっず昔のこずです。

コンパむラヌは、これらのアロケヌタヌを䜿甚しお割り圓おを最適化するこずを蚱可されるべきですか

コンパむラヌは、これらのアロケヌタヌを䜿甚しお割り圓おを最適化するこずを蚱可されるべきですか

@Zoxcどういう意味ですか

基本的にこの理由から、アロケヌタヌずデロケヌタヌの特性を別々に2぀を接続するア゜シ゚ヌトタむプで因数分解するこずを提案しおいたのはずっず昔のこずです。

埌䞖のために、このステヌトメントを明確にしたしょうオフラむンで@ Ericson2314に話したしたアむデアは、 Boxがデアロケヌタヌ䞊でパラメトリックになる可胜性があるずいうこずです。 したがっお、次の実装を行うこずができたす。

trait Allocator {
    type D: Deallocator;

    fn get_deallocator(&self) -> Self::D;
}

trait Deallocator {}

struct Box<T, D: Deallocator> {
    ptr: *mut T,
    d: D,
}

impl<T, D: Deallocator> Box<T, D> {
    fn new_from_allocator<A: Allocator>(x: T, a: A) -> Box<T, A::D> {
        ...
        Box {
            ptr: ptr,
            d: a.get_deallocator()
        }
    }
}

この方法では、呌び出し時にnew_from_allocator堎合は、 A::Dれロサむズのタむプで、その埌、 dのフィヌルドBox<T, A::D>れロのサむズを占めおおり、そう結果のBox<T, A::D>サむズは1ワヌドです。

これがい぀着陞するかに぀いおのタむムラむンはありたすか 私はいく぀かのアロケヌタヌのものに取り組んでいたす、そしおこのものが私が構築するためにそこにあったらいいのにず思いたす。

興味があれば、これにいく぀かのサむクルを貞しおいただければ幞いですが、私はRustに比范的慣れおいないので、初心者のコヌドをコヌドレビュヌする必芁があるずいう点でメンテナの䜜業が増える可胜性がありたす。 誰かの぀た先を螏んだくないし、人のためにもっず仕事をしたくない。

さお、最近、アロケヌタの状態を評䟡するために䌚いたした。これにもいく぀かの良いニュヌスがあるず思いたす。 これらのAPIのサポヌトはただlibstdに䞊陞しおいないようですが、誰もがい぀でも䞊陞するこずに満足しおいたす。

私たちが議論したこずの1぀は、掚論の問題が発生する可胜性があるため、すべおのlibstdタむプを切り替えるのは少し時期尚早かもしれないずいうこずですが、それにもかかわらず、 Allocator特性ずLayoutを着陞させるのは良い考えのようです。 std::heapモゞュヌルを入力したす。

@joshlfここで手䌝いたいのなら、それは倧歓迎だず思いたす 最初の郚分は、このRFCから暙準ラむブラリに基本的な型/特性を導入する可胜性がありたす。その埌、libstdのコレクションの実隓ず詊甚を開始できたす。

@alexcrichtonリンクが壊れおいるず思いたすか ここを指したす。

私たちが議論したこずの1぀は、すべおのlibstdタむプを切り替えるこずは、掚論の問題の可胜性があるため、少し時期尚早かもしれないずいうこずです。

トレむトを远加するこずは良い最初のステップですが、それを䜿甚するために既存のAPIをリファクタリングしないず、あたり䜿甚されたせん。 https://github.com/rust-lang/rust/issues/27336#issuecomment -300721558で、ファサヌドの背埌にある朚枠をすぐにリファクタリングできるこずを提案しstd新しいタむプのラッパヌを远加したす。 やるのは面倒ですが、進歩を遂げるこずができたす。

@alexcrichtonオブゞェクトアロケヌタをここでの議論により、アロケヌタヌの特性ずオブゞェクトの間にほが完党な察称性があるず私は信じおいたす。アロケヌタ特性。 䟋えば、あなたは私は倉曎のようなものがありたすAddressには*mut u8ずの察称性のために*mut TからObjectAllocator<T> ;私たちは、おそらくで終わるだろうAddress<T>たたはそのようなもの

unsafe trait Allocator {
    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);
}
unsafe trait ObjectAllocator<T> {
    unsafe fn alloc(&mut self) -> Result<*mut T, AllocErr>;
    unsafe fn dealloc(&mut self, ptr: *mut T);
}

したがっお、アロケヌタずオブゞェクトアロケヌタの䞡方を同時に実隓するこずは有甚であるず思いたす。 ただし、これがそのための適切な堎所であるかどうか、たたは別のRFCたたは少なくずも別のPRが必芁かどうかはわかりたせん。

ああ、グロヌバルアロケヌタヌに関する情報もあるここにリンク@joshlfはあなたが考えおいるこずですか

@alexcrichtonは、 libstdのどのコレクションにも統合されおいなくおも、 Allocator特性ずLayoutタむプを提䟛するPRを望んでいるようです。

それを正しく理解すれば、そのためのPRを立おるこずができたす。 少なくずもRawVecずVecプロトタむプずの統合を詊み続けおいるので、そうしおいたせんでした。 この時点でRawVec完了したしたが、 DrainやIntoIterなど、他にも倚くの構造が構築されおいるため、 Vecは少し難しいです。 IntoIterなど...

実際、私の珟圚のブランチは実際にビルドされる可胜性があるようですそしお、 RawVecずの統合のための1぀のテストに合栌したしたので、先に進んで投皿したした42313

@hawkwは尋ねたした

明らかな䜕かが欠けおいる堎合は蚱しおください。ただし、このRFCで説明されおいるレむアりト特性がPODであるため、コピヌずクロヌンを実装しない理由はありたすか

私が䜜った理由はLayout実装のみをCloneなくCopy私はより倚くの構造を远加する可胜性開いたたたにしたかったずいうこずですLayoutタむプを。 特に、私はただ持っおしようずしおいるこずに興味がLayoutそれを構築するために䜿甚される任意のタむプの構造を远跡しようずするずの䟋えば16-配列struct { x: u8, y: [char; 215] }アロケヌタがするオプションを持぀こずになりそうずいう、珟圚のコンテンツがどのタむプから構成されおいるかをレポヌトするむンストルメンテヌションルヌチンを公開したす。

これはほが確実にオプション機胜である必芁がありたす。぀たり、開発者に型が豊富なLayoutコンストラクタヌの䜿甚を匷制するこずに反察しおいるようです。 したがっお、この圢匏のむンストルメンテヌションには、タむプ情報を持たない割り圓おを凊理するために、「䞍明なメモリブロック」カテゎリのようなものを含める必芁がありたす。

しかし、それにもかかわらず、このような機胜が、 Layout Copy実装させるこずを遞択しなかった䞻な理由Copy実装は、 Layout自䜓に察する時期尚早な制玄になるず考えたした。

@alexcrichton @pnkfelix

@pnkfelixがこれをカバヌしおいるようで、そのPRが

珟圚、 Allocator::oomの眲名は次のずおりです。

    fn oom(&mut self, _: AllocErr) -> ! {
        unsafe { ::core::intrinsics::abort() }
    }

それはされた私の泚意に持っお来らGeckoは少なくずもOOM䞊にも割り圓おサむズを知るのが奜きずいうこず、けれども、。 OOMが発生しおいる理由ずしおOption<Layout>ようなコンテキストを远加するために安定化するずきに、これを考慮したいず思うかもしれたせん。

@alexcrichton
耇数のoom_xxxバリアント、たたは異なる匕数タむプの列挙型を䜿甚する䟡倀がありたすか 倱敗する可胜性のあるメ゜ッドにはいく぀かの異なるシグネチャがありたずえば、 allocはレむアりトを取り、 reallocはポむンタ、元のレむアりト、新しいレむアりトを取りたすなど、 oomようなメ゜ッドがそれらすべおに぀いお知りたい堎合です。

@joshlfそれは本圓です、はい、しかしそれが有甚かどうかは


ここでの安定化のポむントは、「 fn dealloc提䟛されるアラむメントの芁件を決定する」こずでもあり、Windowsでのdeallocの珟圚の実装では、 alignを䜿甚しお正しく無料。 @ruudaあなたはこの事実に興味があるかもしれたせん。

ここでの安定化のポむントは、「 fn dealloc提䟛されるアラむメントの芁件を決定する」こずでもあり、Windowsでのdeallocの珟圚の実装では、 alignを䜿甚しお正しく無料。

はい、これが私が最初にこれに遭遇した方法だず思いたす。 このため、私のプログラムはWindowsでクラッシュしたした。 HeapAllocは配眮の保蚌を行わないため、 allocateはより倧きな領域を割り圓お、元のポむンタヌをヘッダヌに栌玍したすが、最適化ずしお、配眮芁件が満たされる堎合はこれを回避したす。 この最適化を倱うこずなく、 HeapAllocを無料でアラむメントを必芁ずしないアラむメント察応アロケヌタに倉換する方法があるのだろうか。

@ruuda

HeapAllocはアラむメントを保蚌しないため

32ビットの堎合は8バむト、64ビットの堎合は16バむトの最小アラむメント保蚌を提䟛したすが、それより高いアラむメントを保蚌する方法は提䟛したせん。

Windows䞊のCRTによっお提䟛される_aligned_mallocは、より高いアラむメントの割り圓おを提䟛できたすが、特に、 freeは違法であるため、 _aligned_freeずペアにする必芁がmallocたたは_aligned_mallocどちらで行われたかわからない堎合は、Windowsでalloc_systemが䜿甚されおいるのず同じ難問に陥っおいたす。 deallocateの配眮を知っおいたす。 CRTは、 freeず組み合わせるこずができる暙準のaligned_alloc関数を提䟛しおいないため、Microsoftでさえこの問題を解決できたせんでした。 これはC11関数であり、MicrosoftはC11をサポヌトしおいないため、これは匱い議論です。

deallocateは、䜍眮合わせのみを考慮しお、䜍眮合わせがオヌバヌアラむンされおいるかどうかを認識したす。実際の倀自䜓は関係ありたせん。 真にアラむメントに䟝存しないdeallocateが必芁な堎合は、すべおの割り圓おをオヌバヌアラむメントずしお扱うこずができたすが、小さな割り圓おでは倚くのメモリを浪費したす。

@alexcrichtonは曞いた

珟圚、 Allocator::oomの眲名は次のずおりです。

    fn oom(&mut self, _: AllocErr) -> ! {
        unsafe { ::core::intrinsics::abort() }
    }

それはされた私の泚意に持っお来らGeckoは少なくずもOOM䞊にも割り圓おサむズを知るのが奜きずいうこず、けれども、。 OOMが発生しおいる理由ずしおOption<Layout>ようなコンテキストを远加するために安定化するずきに、これを考慮したいず思うかもしれたせん。

AllocErr Layoutは、 AllocErr::ExhaustedバリアントのLayoutが既に含たれおいたす。 LayoutをAllocErr::Unsupportedバリアントに远加するこずもできたす。これは、クラむアントの期埅の芳点から最も簡単だず思いたす。  AllocErr列挙型自䜓の偎面を単玔に増やすずいう欠点がありたすが、それに぀いお心配する必芁はないかもしれたせん...

ああ、必芁なのはそれだけだず思いたす。@ pnkfelixの修正に感謝したす。

https://github.com/rust-lang/rust/pull/42727が着陞した埌になるので、䞀般的にstd::heapの远跡問題のためにこの問題の転甚を開始したす。 これに賛成しお、他のいく぀かの関連する問題を閉じたす。

コレクションを倉換するための远跡の問題はありたすか PRが統合されたので、

  • 関連する゚ラヌタむプに぀いお話し合う
  • ロヌカルアロケヌタを䜿甚するようにコレクションを倉換するこずに぀いお話し合いたす特に関連する゚ラヌタむプを掻甚したす

https://github.com/rust-lang/rust/issues/42774を開いお、 Alloc stdコレクションぞの統合を远跡したした。 std::heapモゞュヌルの最初のパスずは別の安定化の軌道に乗っおいる可胜性が高い、libsチヌムでの歎史的な議論がありたす。

アロケヌタヌ関連の問題を確認しおいるずきに、しばらく前にhttps://github.com/rust-lang/rust/issues/30170にも出くわしたした。 OSXシステムアロケヌタはアラむメントが高くバグが倚いようです。そのプログラムをjemallocで実行するず、少なくずもLinuxでの割り圓お解陀䞭にセグフォヌルトが発生したす。 安定化䞭に怜蚎する䟡倀がありたす

れロサむズの割り圓おが芁求された配眮ず䞀臎する必芁があるかどうかずいう特定の質問を議論する堎所ずしお、42794を開きたした。

たあ、れロサむズの割り圓おはナヌザヌアロケヌタヌでは違法です

alloc::heap::allocate関数ずその仲間がNightlyでなくなったので、この新しいAPIを䜿甚するようにServoを曎新したした。 これは差分の䞀郚です

-use alloc::heap;
+use alloc::allocator::{Alloc, Layout};
+use alloc::heap::Heap;
-        let ptr = heap::allocate(req_size as usize, FT_ALIGNMENT) as *mut c_void;
+        let layout = Layout::from_size_align(req_size as usize, FT_ALIGNMENT).unwrap();
+        let ptr = Heap.alloc(layout).unwrap() as *mut c_void;

人間工孊は良くないず思いたす。 1぀のアむテムのむンポヌトから2぀の異なるモゞュヌルからの3぀のアむテムのむンポヌトに移行したした。

  • allocator.alloc(Layout::from_size_align(
))䟿利な方法があるのは理にかなっおいたすか
  • <Heap as Alloc>::_メ゜ッドを無料の関数たたは固有のメ゜ッドずしお利甚できるようにするこずは理にかなっおいたすか むンポヌトするアむテムを1぀少なくするには、 Alloc特性を䜿甚したす。

あるいは、 Alloc特性が前奏曲に含たれおいる可胜性がありたすか、それずもナヌスケヌスのニッチすぎるのでしょうか。

@SimonSapin IMOは、このような䜎レベルAPIの人間工孊を最適化するこずにあたり

@SimonSapin

人間工孊は良くないず思いたす。 1぀のアむテムのむンポヌトから2぀の異なるモゞュヌルからの3぀のアむテムのむンポヌトに移行したした。

私は自分のコヌドベヌスずたったく同じ感芚を持っおいたした-今はかなり䞍栌奜です。

allocator.alloc(Layout::from_size_align(
))?䟿利な方法があるのは理にかなっおいたすか

Alloc特性ですか、それずもHeapですか ここで考慮すべきこずの1぀は、3番目の゚ラヌ条件があるこずです。 Layout::from_size_alignはOption返すため、割り圓お時に発生する可胜性のある通垞の゚ラヌに加えおNoneを返す可胜性がありたす。 。

あるいは、 Alloc特性が前奏曲に含たれおいる可胜性がありたすか、それずもナヌスケヌスのニッチすぎたすか

IMOは、このような䜎レベルAPIの人間工孊を最適化するこずにあたり意味がありたせん。

プレリュヌドを入れるにはおそらく䜎レベルであるこずに同意したすが、それでも人間工孊を最適化するこずには䟡倀があるず思いたす少なくずも、利己的に-それは本圓に厄介なリファクタリングでした😝。

@SimonSapin以前にOOMを扱ったこずがありたせんか たた、 std 、3぀のタむプすべおがstd::heapモゞュヌルで䜿甚できたすこれらは1぀のモゞュヌルに含たれおいるはずです。 たた、以前はサむズがあふれるケヌスに察応しおいたせんでしたか たたはれロサむズのタむプ

以前にOOMを扱ったこずがありたせんか

それが存圚する堎合、 alloc::heap::allocate関数はResultなしでポむンタヌを返し、OOM凊理に遞択肢を残したせんでした。 プロセスを䞭止したず思いたす。 スレッドをパニックにするために.unwrap()を远加したした。

それらは1぀のモゞュヌルにあるはずです

heap.rsにpub use allocator::*;が含たれおいるこずがわかりたす。 しかし、rustdocペヌゞにリストされおいるimplでHeap Allocをクリックするず、 alloc::allocator::Allocに送られたした。

残りに぀いおは、私はそれを調べおいたせん。 私は䜕幎も前に曞かれた倧量のコヌドを新しいコンパむラに移怍しおいたす。 これらは、CラむブラリであるFreeTypeのコヌルバックだず思いたす。

alloc :: heap :: alllocate関数が存圚する堎合、結果なしでポむンタヌを返し、OOM凊理に遞択肢を残したせんでした。

それはあなたに遞択肢を䞎えたした。 返されたポむンタヌは、ヒヌプアロケヌタヌが割り圓おに倱敗したこずを瀺すnullポむンタヌである可胜性がありたす。 これが、 Resultに切り替えお、人々がそのケヌスを凊理するこずを忘れないようにしたこずをずおもうれしく思う理由です。

たあ、たぶんFreeTypeがnullチェックをしおしたったのかもしれたせんが、私にはわかりたせん。 ずにかく、はい、結果を返すこずは良いこずです。

30170ず43097を考えるず、ナヌザヌがアラむメントを芁求もなく倧きなアラむメントでOSXの問題を解決したいず思いたす> = 1 << 32 。

これを匷制する1぀の非垞に簡単な方法倉曎Layoutむンタヌフェヌスので、 alignで衚されるu32の代わりにusize 。

@alexcrichtonこれに぀いお考えがありたすか これを行うPRを䜜成する必芁がありたすか

@pnkfelix Layout::from_size_alignはただusizeを取り、 u32オヌバヌフロヌで゚ラヌを返したすよね

@SimonSapin静的な前提条件が、倀> = 1 << 32を枡すこずが安党でない堎合、 usize敎列を継続す​​る理由は䜕ですか

答えが「䞀郚のアロケヌタはアラむメント> = 1 << 32サポヌトしおいる可胜性がありたす」の堎合、珟状に戻り、私の提案は無芖しおかたいたせん。 私の提案のポむントは基本的にこのようなコメントぞの「+1」です

std::mem::align_ofはusize返すため

@SimonSapinああ、叀き良き安定したAPIの...ため息を぀く。

@pnkfelixを1 << 32制限するこず

@rfcbotfcpマヌゞ

わかりたした。この特性ずそのタむプはしばらくの間焌き付けられおおり、開始以来、暙準コレクションの基瀎ずなる実装でもありたす。 私は、特に保守的な新芏株匏公開から始めるこずを提案したす。぀たり、次のむンタヌフェヌスのみを安定させるこずです。

pub struct Layout { /* ... */ }

extern {
    pub type void;
}

impl Layout {
    pub fn from_size_align(size: usize, align: usize) -> Option<Layout>;
    pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout;

    pub fn size(&self) -> usize;
    pub fn align(&self) -> usize;
}

pub unsafe trait Alloc {
    unsafe fn alloc(&mut self, layout: Layout) -> *mut void;
    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> *mut void;
    unsafe fn dealloc(&mut self, ptr: *mut void, layout: Layout);

    // all other methods are default and unstable
}

/// The global default allocator
pub struct Heap;

impl Alloc for Heap {
    // ...
}

impl<'a> Alloc for &'a Heap {
    // ...
}

/// The "system" allocator
pub struct System;

impl Alloc for System {
    // ...
}

impl<'a> Alloc for &'a System {
    // ...
}

元の提案

pub struct Layout { /* ... */ }

impl Layout {
    pub fn from_size_align(size: usize, align: usize) -> Option<Layout>;
    pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout;

    pub fn size(&self) -> usize;
    pub fn align(&self) -> usize;
}

// renamed from AllocErr today
pub struct Error {
    // ...
}

impl Error {
    pub fn oom() -> Self;
}

pub unsafe trait Alloc {
    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, Error>;
    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);

    // all other methods are default and unstable
}

/// The global default allocator
pub struct Heap;

impl Alloc for Heap {
    // ...
}

impl<'a> Alloc for &'a Heap {
    // ...
}

/// The "system" allocator
pub struct System;

impl Alloc for System {
    // ...
}

impl<'a> Alloc for &'a System {
    // ...
}

特に

  • 今のずころ、 Allocトレむトのalloc 、 alloc_zeroed 、およびdeallocメ゜ッドのみを安定させたす。 これにより、カスタムグロヌバルアロケヌタを定矩するずいう、今日の最も差し迫った問題が解決されるず思いたす。
  • Errorタむプを削陀しお、生のポむンタヌのみを䜿甚するようにしたす。
  • むンタヌフェむスのu8タむプをvoid
  • Layoutタむプの簡略版。

deallocずアラむンメント正確なアラむンメント適合䞍明をどうするかなどの未解決の質問がただありたすが、APIではない可胜性が高いため、FCP䞭にそれらを解決できるこずを望んでいたす-砎壊的な倉化。

䜕かを安定させるために+1

AllocErr名前をErrorし、むンタヌフェむスをもう少し保守的にしたす。

これにより、アロケヌタがUnsupportedを指定するオプションがなくなりたすか 私がたくさんハヌプしおいる䜕かにもっずハヌプする危険を冒しお、私は44557がただ問題であるず思いたす。

Layout

Layoutからいく぀かのメ゜ッドを削陀したようです。 陀倖したものを実際に削陀する぀もりでしたか、それずも䞍安定なたたにしおおく぀もりでしたか

impl Error {
    pub fn oom() -> Self;
}

これは今日のAllocErr::Exhaustedのコンストラクタヌですか もしそうなら、それはLayoutパラメヌタを持぀べきではありたせんか

チヌムメンバヌの@alexcrichtonは、これをマヌゞするこずを提案したした。 次のステップは、タグ付けされた残りのチヌムによるレビュヌです。

  • [x] @BurntSushi
  • [x] @Kimundi
  • [x] @alexcrichton
  • [x] @aturon
  • [x] @cramertj
  • [x] @dtolnay
  • [x] @eddyb
  • [x] @nikomatsakis
  • [x] @nrc
  • [x] @pnkfelix
  • [x] @sfackler
  • [x] @withoutboats

懞念事項

これらのレビュヌアがコンセンサスに達するず、これは最終コメント期間に入りたす。 このプロセスのどの時点でも提起されおいない倧きな問題を芋぀けた堎合は、声を䞊げおください。

タグ付けされたチヌムメンバヌが私に䞎えるこずができるコマンドに぀いおは、このドキュメントを参照しおください。

私はこの仕事のいく぀かを安定させるこずに本圓に興奮しおいたす

1぀の質問䞊蚘のスレッドで、 @ joshlfず@ Ericson2314は、 alloc堎合に最適化するために、 AllocずDealloc特性を分離する可胜性に぀いお興味深い点を提起したした。 allocはいく぀かのデヌタが必芁ですが、 deallocは远加情報を必芁ずしないため、 Deallocタむプのサむズをれロにするこずができたす。

この質問は解決されたしたか 2぀の特性を分離するこずの欠点は䜕ですか

@joshlf

これにより、アロケヌタがサポヌトされおいないこずを指定するオプションがなくなりたすか

はい、いいえ、それはそのような操䜜が安定したさびですぐにサポヌトされないこずを意味したすが、䞍安定なさびでそれをサポヌトし続けるこずができたす。

陀倖したものを実際に削陀する぀もりでしたか、それずも䞍安定なたたにしおおく぀もりでしたか

確かに ここでも、安定したAPI衚面積を提案しおいるだけですが、他のすべおのメ゜ッドは䞍安定なたたにしおおくこずができたす。 時間の経過ずずもに、より倚くの機胜を安定させ続けるこずができたす。 できるだけ保守的に始めるのが最善だず思いたす。


@SimonSapin

これは、今日のAllocErr :: Exhaustedのコンストラクタヌですか もしそうなら、それはレむアりトパラメヌタを持぀べきではありたせんか

ああ良い点 本圓に必芁な堎合はErrorをれロサむズのタむプにする可胜性を残したかったのですが、もちろん、レむアりトの取埗方法を䞍安定に保ち、必芁に応じお安定させるこずができたす。 それずも、レむアりトを維持するErrorを最初のパスで安定させる必芁があるず思いたすか


@cramertj

私はただそのような質問/懞念を個人的に芋たこずがありたせんでしたが私はそれを芋逃したず思いたす、私はそれが䟡倀があるず個人的には芋たせんでした。 たずえば、コレクションにAlloc + Deallocず入力する必芁があるため、2぀の特性は䞀般に定型文の2倍になりたす。 このような特殊な甚途では、他のすべおのナヌザヌが最終的に䜿甚するむンタヌフェむスに個人的に通知したくないず思いたす。

@cramertj @alexcrichton

私はただそのような質問/懞念を個人的に芋たこずがありたせんでしたが私はそれを芋逃したず思いたす、私はそれが䟡倀があるず個人的には芋たせんでした。

䞀般的に、1぀の明癜な䟋倖を陀いおそれは䟡倀がないこずに同意したす Box 。 Box<T, A: Alloc>は、珟圚のAlloc定矩を考えるず、少なくずも2ワヌドの倧きさである必芁がありたすすでに持っおいるポむンタヌず、少なくずもAllocぞの参照 グロヌバルシングルトンZSTずしお実装可胜の堎合を陀きたす。 このような䞀般的で基本的なタむプを栌玍するために必芁なスペヌスでの2倍たたはそれ以䞊の爆発が私には関係しおいたす。

@alexcrichton

今のように、誰もがたずえばコレクションにAlloc + Deallocず入力する必芁がありたす

次のようなものを远加できたす。

trait Allocator: Alloc + Dealloc {}
impl<T> Allocator for T where T: Alloc + Dealloc {}

このような䞀般的で基本的なタむプを栌玍するために必芁なスペヌスでの2倍たたはそれ以䞊の爆発

プロセスグロヌバルではないカスタムアロケヌタを䜿甚する堎合のみ。 std::heap::Heap デフォルトはれロサむズです。

それずも、最初のパスでレむアりト保存゚ラヌを安定させる必芁があるず思いたすか

@alexcrichtonこの提案された最初のパスがなぜそれであるのか私は本圓に理解しおいたせん。 Vec悪甚するこずですでに実行できる以䞊のこずはほずんどなく、たずえばhttps://crates.io/crates/jemallocatorを䜿甚するには十分ではありたせん

党䜓を安定させるためにただ解決する必芁があるものは䜕ですか

プロセスグロヌバルではないカスタムアロケヌタを䜿甚する堎合のみ。 std :: heap :: Heapデフォルトはれロサむズです。

これは、パラメトリックアロケヌタヌを䜿甚する䞻なナヌスケヌスのようです。 次のツリヌの簡単な定矩を想像しおみおください。

struct Node<T, A: Alloc> {
    t: T,
    left: Option<Box<Node<T, A>>>,
    right: Option<Box<Node<T, A>>>,
}

1ワヌドのAllocを持぀ツリヌから構築されたツリヌは、ZST Allocず比范しお、デヌタ構造党䜓のサむズが玄1.7倍になりたす。 それは私にはかなり悪いように思えたす、そしおこれらの皮類のアプリケヌションはAlloc特性にするずいう党䜓的なポむントのようなものです。

@cramertj

次のようなものを远加できたす。

たた、実際の特性゚むリアスも甚意したす:) https://github.com/rust-lang/rust/issues/41517

@glaebhoerlええ、でもただ実装がないので、安定化はただAllocator手動実装を無効にするず、特性に切り替えるこずができるず思いたす-゚むリアスは逆方向に-互換性がありたす;

@joshlf

このような䞀般的で基本的なタむプを栌玍するために必芁なスペヌスでの2倍たたはそれ以䞊の爆発が私には関係しおいたす。

今日のすべおの実装は、サむズがれロの型か、ポむンタが倧きいだけだず思いたすよね 䞀郚のpointer-size-typesをれロサむズにするこずができる最適化はありたせんか たたはそのようなもの


@cramertj

次のようなものを远加できたす。

確かに ただし、1぀の特性を3぀にしたした。 過去に、私たちはそのような特性で玠晎らしい経隓をしたこずがありたせん。 たずえば、 Box<Both>はBox<OnlyOneTrait>キャストされたせん。 蚀語機胜がこれらすべおをスムヌズにするのを埅぀こずができるず確信しおいたすが、せいぜい、それらは遠い道のりのようです。


@SimonSapin

党䜓を安定させるためにただ解決する必芁があるものは䜕ですか

知りたせん。 議論が少なくなるように、絶察に小さいものから始めたかったのです。

今日のすべおの実装は、サむズがれロの型か、ポむンタが倧きいだけだず思いたすよね 䞀郚のpointer-size-typesをれロサむズにするこずができる最適化はありたせんか たたはそのようなもの

ええ、アむデアは、あなたのタむプのアロケヌタヌから割り圓おられたオブゞェクトぞのポむンタヌが䞎えられれば、それがどのむンスタンスから来たのかを理解できるずいうこずです䟋えば、むンラむンメタデヌタを䜿甚しお。 したがっお、割り圓おを解陀する必芁がある唯䞀の情報は、ランタむム情報ではなく、タむプ情報です。

割り圓お解陀の調敎に戻るには、2぀の方法がありたす。

  • 提案どおりに安定させたす割り圓お解陀の調敎を行いたす。 Layoutが含たれおいない限り、手動で割り圓おられたメモリの所有暩を譲枡するこずは䞍可胜です。 特に、 Vec 、 Box 、 Stringたたはその他のstdコンテナを、必芁以䞊に厳密に配眮しお構築するこずはできたせんたずえば、ボックス化された芁玠がキャッシュラむンにたたがるのは望たしくありたせん、埌で手動で分解しお割り圓おを解陀する必芁はありたせんこれは垞にオプションであるずは限りたせん。 䞍可胜なこずの別の䟋は、simd操䜜を䜿甚しおVecを埋め、それを配るこずです。

  • 割り圓お解陀時に調敎を必芁ずせず、WindowsのHeapAllocベヌスのalloc_systemから小さな割り圓おの最適化を削陀したす。 垞に配眮を保存しおください。 @alexcrichton 、あなたがそのコヌドをコミットしたそもそもなぜそこに眮かれたのか芚えおいたすか 実際のアプリケヌションでかなりの量のメモリを節玄できるずいう蚌拠はありたすか マむクロベンチマヌクを䜿甚するず、割り圓おサむズに応じおどちらの方法でも結果を出すこずができたす—ずにかくHeapAllocがサむズを切り䞊げおいた堎合を陀きたす。

いずれにせよ、これは非垞に難しいトレヌドオフです。 メモリずパフォヌマンスぞの圱響は、アプリケヌションのタむプに倧きく䟝存し、どちらを最適化するかはアプリケヌション固有です。

私たちは実際にはJustFineTMかもしれないず思いたす。 Allocドキュメントの匕甚

䞀郚の方法では、レむアりトがメモリブロックに適合する必芁がありたす。
レむアりトがメモリブロックに「適合する」ずは、たたは
同等に、メモリブロックがレむアりトに「適合する」ためには
次の2぀の条件が満たされおいる必芁がありたす。

  1. ブロックの開始アドレスはlayout.align()揃える必芁がありたす。

  2. ブロックのサむズは[use_min, use_max]範囲内にある必芁がありたす。ここで、

    • use_minはself.usable_size(layout).0であり、

    • use_maxは、以前のたたは以前の容量です。
      ifぞの呌び出しを介しおブロックが割り圓おられたずきに返されたす
      alloc_excessたたはrealloc_excess 。

ご了承ください

  • ブロックの割り圓おに最近䜿甚されたレむアりトのサむズ
    [use_min, use_max]範囲内にあるこずが保蚌されおおり、

  • use_max䞋限は、ぞの呌び出しによっお安党に抂算できたす。
    usable_size 。

  • レむアりトkがメモリブロックに適合する堎合 ptr瀺される
    珟圚、アロケヌタaを介しお割り圓おられおいる堎合、
    そのレむアりトを䜿甚しお、割り圓おを解陀したす。぀たり、 a.dealloc(ptr, k);です。

最埌の箇条曞きに泚意しおください。 私は、アラむメントずレむアりトを割り圓おる堎合はa私は、アラむメントに解攟するために、それは法的でなければなりたせんb < aに敎列されたオブゞェクトので、 aたたに敎列されたすbであるため、配眮がbのレむアりトは、配眮がa 同じサむズのレむアりトで割り圓おられたオブゞェクトに適合したす。

これが意味するのは、特定のタむプに必芁な最小アラむメントよりも倧きいアラむメントで割り圓おおから、他のコヌドが最小アラむメントで割り圓おを解陀できるようにする必芁があるずいうこずです。これで機胜するはずです。

䞀郚のpointer-size-typesをれロサむズにするこずができる最適化はありたせんか たたはそのようなもの

最近これに関するRFCがあり、互換性の懞念のために実行できる可胜性は非垞に䜎いようです https 

たずえば、 Box<Both>はBox<OnlyOneTrait>キャストされたせん。 蚀語機胜がこれらすべおをスムヌズにするのを埅぀こずができるず確信しおいたすが、せいぜい、それらは遠い道のりのようです。

䞀方、トレむトオブゞェクトのアップキャストは議論の䜙地なく望たしいようであり、ほずんどの堎合、それを実装するための努力/垯域幅/意志力の問題です。 最近スレッドがありたした https 

@ruuda私はそのalloc_system実装を最初に曞いた人でした。 alexcrichtonは、 <time period>の優れたアロケヌタヌリファクタリング䞭にそれを移動しただけです。

珟圚の実装では、特定のメモリブロックを割り圓おたのず同じ配眮で割り圓おを解陀alloc_systemが倉曎されるたで、誰もが埓わなければならない珟圚の珟実です。

Windowsでの割り圓おでは、垞にMEMORY_ALLOCATION_ALIGNMENT倍数が䜿甚されたすただし、バむトに割り圓おたサむズは蚘憶されおいたす。 MEMORY_ALLOCATION_ALIGNMENTは、32ビットでは8、64ビットでは16です。 オヌバヌアラむンされたタむプの堎合、アラむンメントがMEMORY_ALLOCATION_ALIGNMENTより倧きいため、 alloc_systemによっお生じるオヌバヌヘッドは䞀貫しお指定されたアラむンメントの量になり、64バむトのアラむンされた割り圓おには64バむトのオヌバヌヘッドがありたす。

そのオヌバヌアラむンされたトリックをすべおの割り圓おに拡匵するこずにした堎合割り圓お時に指定したのず同じアラむンメントで割り圓おを解陀する芁件がなくなりたす、より倚くの割り圓おにオヌバヌヘッドが発生したす。 アラむンメントがMEMORY_ALLOCATION_ALIGNMENTず同じである割り圓おでは、 MEMORY_ALLOCATION_ALIGNMENTバむトの䞀定のオヌバヌヘッドが発生したす。 アラむンメントがMEMORY_ALLOCATION_ALIGNMENT未満の割り圓おでは、玄半分の時間でMEMORY_ALLOCATION_ALIGNMENTバむトのオヌバヌヘッドが発生したす。 MEMORY_ALLOCATION_ALIGNMENT切り䞊げられた割り圓おのサむズが、割り圓おのサむズにポむンタヌのサむズを加えたもの以䞊の堎合、オヌバヌヘッドはありたせん。それ以倖の堎合はオヌバヌヘッドがありたす。 割り圓おの99.99がオヌバヌアラむンされないこずを考えるず、これらすべおの割り圓おにそのようなオヌバヌヘッドが本圓に発生したいですか

@ruuda

個人的には、今日のWindowsでのalloc_systemの実装は、 Vecような別のコンテナヌぞの割り圓おの所有暩を攟棄する機胜よりも倧きなメリットがあるず感じおいたす。 AFAIKですが、垞にアラむメントをパディングし、割り圓お解陀にアラむメントを必芁ずしないこずの圱響を枬定するデヌタはありたせん。

@joshlf

Windowsのalloc_systemは、割り圓おで枡されたのず同じ配眮が割り圓お解陀に枡されるこずに䟝存しおいるため、コメントは間違っおいるず思いたす。

割り圓おの99.99がオヌバヌアラむンされないこずを考えるず、これらすべおの割り圓おにそのようなオヌバヌヘッドが本圓に発生したいですか

オヌバヌヘッドが倧きいかどうか、およびメモリたたはパフォヌマンスを最適化するかどうかは、アプリケヌションによっお異なりたす。 私の疑惑は、ほずんどのアプリケヌションでどちらも問題ないずいうこずですが、少数の少数掟がメモリに深く関心を持っおおり、実際にはそれらの䜙分なバむトを買う䜙裕はありたせん。 そしお、別の少数掟はアラむメントを制埡する必芁があり、圌らは本圓にそれを必芁ずしおいたす。

@alexcrichton

Windowsのalloc_systemは、割り圓おで枡されたのず同じ配眮が割り圓お解陀に枡されるこずに䟝存しおいるため、コメントは間違っおいるず思いたす。

これは、Windowsのalloc_systemが実際にAllocトレむトを適切に実装しおいないこずを意味したせんかしたがっお、 Allocトレむトの芁件を倉曎する必芁があるかもしれたせん。


@ retep998

私があなたのコメントを正しく読んでいる堎合、別の配眮で割り圓おを解陀できる必芁があるかどうかに関係なく、すべおの割り圓おにその配眮のオヌバヌヘッドが存圚したせんか ぀たり、64バむトのアラむンメントで64バむトを割り圓お、64バむトのアラむンメントでも割り圓おを解陀した堎合、説明したオヌバヌヘッドは䟝然ずしお存圚したす。 したがっお、通垞よりも倧きい配眮を芁求する機胜であるため、さたざたな配眮を割り圓お解陀できる機胜ではありたせん。

@joshlf alloc_systemによっお匕き起こされるオヌバヌヘッドは、珟圚、通垞よりも倧きい配眮を芁求するこずによるものです。 配眮がMEMORY_ALLOCATION_ALIGNMENT以䞋の堎合、 alloc_systemによるオヌバヌヘッドはありたせん。

ただし、異なる配眮での割り圓お解陀を蚱可するように実装を倉曎した堎合、配眮に関係なく、オヌバヌヘッドはほがすべおの割り圓おに適甚されたす。

ああ、分かった; 理にかなっおいたす。

ヒヌプずヒヌプの䞡方にAllocを実装するこずの意味は䜕ですか どのような堎合に、ナヌザヌはこれらのimplの1぀ず他のimplを䜿甚したすか

これは、 *mut u8が「䜕でもポむンタ」を意味する最初の暙準ラむブラリAPIですか String :: from_raw_partsがありたすが、それは実際にはバむトぞのポむンタを意味したす。 私は「䜕でもポむンタ」を意味する*mut u8ファンではありたせん。 他のオプションは䜕ですか 䞍透明OPAQUE型ぞのポむンタの方が意味があるかもしれたせん。

@rfcbot懞念* mut u8

@dtolnay Alloc for Heapは䞀皮の「暙準」であり、 Alloc for &HeapはWrite for &Tようなもので、特性には&mut selfが必芁ですが、実装には必芁ありたせん。 特に、 HeapやSystemようなタむプはスレッドセヌフであり、割り圓おるずきに同期する必芁がないこずを意味したす。

ただし、さらに重芁なのは、 #[global_allocator]するには、接続先の静的なタむプがT 、 Alloc for &Tです。 別名、すべおのグロヌバルアロケヌタヌはスレッドセヌフである必芁がありたす

*mut u8 、 *mut ()は面癜いかもしれないず思いたすが、個人的には、ここで「これを正しく行う」こず自䜓を匷いられおいるずは感じおいたせん。

*mut u8の䞻な利点は、バむトオフセットで.offsetを䜿甚するず非垞に䟿利なこずです。

*mut u8 、 *mut ()は面癜いかもしれないず思いたすが、個人的には、ここでそれ自䜓を「正しく理解する」こずを匷いられおいるずは感じおいたせん。

安定したむンタヌフェヌスで*mut u8を䜿甚する堎合、自分自身を固定したせんか 蚀い換えれば、これを安定させれば、将来「これを正しくする」機䌚はありたせん。

たた、将来RFC 2040のような最適化を行う堎合に備えお、 *mut ()は私には少し危険に思えたす。

*mut u8の䞻な利点は、バむトオフセットで.offsetを䜿甚するず非垞に䟿利なこずです。

本圓ですが、簡単にlet ptr = (foo as *mut u8)を実行しおから、陜気な方法で進むこずができたす。 説埗力のある代替案がある堎合、それはAPIで*mut u8に固執する動機ずしおは十分ではないようです公平を期すために、それがあるかどうかはわかりたせん。

たた、将来RFC 2040のような最適化を行う堎合に備えお、* mutは少し危険に思えたす。

その最適化はおそらくすでに起こらないでしょう-それはあたりにも倚くの既存のコヌドを壊しおしたうでしょう。 それがなかったずしおも、それはに適甚される&()ず&mut () 、ない*mut () 。

RFC 1861が実装/安定化に近づいた堎合は、それを䜿甚するこずをお勧めしたす。

extern { pub type void; }

pub unsafe trait Alloc {
    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut void, Error>;
    unsafe fn dealloc(&mut self, ptr: *mut void, layout: Layout);
    // ...
}

たぶん遠すぎたすよね

@joshlf私はそれらに぀いおPRが開いおいるのを芋たず思いたした、残りの未知数はDynSizedです。

これは、オブゞェクトのような構造䜓ハックで機胜したすか 次のようなNode<T>ずしたす。

struct Node<T> {
   size: u32,
   data: T,
   // followed by `size` bytes
}

および倀型

struct V {
  a: u32,
  b: bool,
}

ここで、 1回の割り圓おでサむズ7の文字列を䜿甚しおNode<V>を割り圓おたいず思いたす。 理想的には、サむズ16の割り圓おを4に揃えお、それにすべおを収めたいず思いたす。4はu32 、5はV 、7は文字列バむトです。 これが機胜するのは、 Vの最埌のメンバヌの配眮が1であり、文字列バむトにも配眮1があるためです。

パックドストレヌゞぞの曞き蟌みは未定矩の動䜜であるため、タむプが䞊蚘のように構成されおいる堎合、これはC / C ++では蚱可されないこずに泚意しおください。 これはC / C ++暙準の穎であり、残念ながら修正できないず思いたす。 これが壊れおいる理由を詳しく説明できたすが、代わりにRustに焊点を圓おたしょう。 これは機胜したすか :-)

Node<V>構造自䜓のサむズず配眮に関しおは、Rustコンパむラの気たぐれにかなり慣れおいたす。 Rustは、スタック、ヒヌプ、参照の背埌など、 Node<V>オブゞェクトを想定しお最適化を行う可胜性があるため、Rustが必芁ずするサむズたたは配眮よりも小さいサむズたたは配眮で割り圓おるのはUB未定矩の動䜜です。 -コンパむル時に予想されるものず䞀臎するサむズず配眮を持っおいたす。

実際には、答えは残念ながらノヌのようです。このプログラムを実行したずころ、少なくずもRust Playgroundでは、 Node<V>のサむズが12、配眮が4であるこずがわかりたした。぀たり、 Node<V>は、少なくずも12バむトオフセットする必芁がありたす。 Node<V>内のdata.bフィヌルドのオフセットは8バむトのように芋えたす。これは、バむト9〜11が末尟のパディングであるこずを意味したす。 残念ながら、これらのパディングバむトはある意味で「䜿甚されおいたせん」が、コンパむラはそれらをNode<V>䞀郚ずしお扱い、最も重芁なこずずしお、曞き蟌みを含めお奜きなこずを行う暩利を留保したす。 Node<V>に割り圓おるず、そこに䜙分なデヌタをリスしようずするず、䞊曞きされる可胜性があるこずを意味したす。

泚Rustコンパむラヌがパックされおいるずは思わないタむプをパックされたものずしお扱うこずはできたせん。ただし、䜕かがパックされおいるこずをRustコンパむラヌに䌝えるこずができたす。これにより、タむプのレむアりトが倉曎されたすパディングが削陀されたす。 repr(packed) 

ただし、䞡方を同じRustタむプの䞀郚にせずに次々にオブゞェクトをレむアりトするこずに関しおは、これが有効であるずほが100確信しおいたす-結局のずころ、 Vecが行うこずです。 Layoutタむプのメ゜ッドを䜿甚しお、合蚈割り圓おに必芁なスペヌスの量を動的に蚈算できたす。

let node_layout = Layout::new::<Node<V>>();
// NOTE: This is only valid if the node_layout.align() is at least as large as mem::align_of_val("a")!
// NOTE: I'm assuming that the alignment of all strings is the same (since str is unsized, you can't do mem::align_of::<str>())
let padding = node_layout.padding_needed_for(mem::align_of_val("a"));
let total_size = node_layout.size() + padding + 7;
let total_layout = Layout::from_size_align(total_size, node_layout.align()).unwrap();

このようなものは機胜したすか

#[repr(C)]
struct Node<T> {
   size: u32,
   data: T,
   bytes: [u8; 0],
}

 次に、より倧きなサむズで割り圓お、 slice::from_raw_parts_mut(node.bytes.as_mut_ptr(), size)たすか

詳现な回答をありがずう@joshlf  私のナヌスケヌスのTLDRは、サむズ16のNode<V>を取埗できるずいうものですが、Vがrepr(packed)堎合に限りたす。 それ以倖の堎合、私ができる最善の方法はサむズ1912 + 7です。

@SimonSapinわからない; 詊しおみたす。

本圓にこのスレッドに远い぀いたが、私はただ䜕を安定化に察しお死んでセットしおいたせんでした。 難しい問題の実装はただ進んでいたせん。

  1. アロケヌタヌ-倚型コレクション

    • 肥倧化しおいない箱すらありたせん

  2. 間違いのないコレクション

私は過去数ヶ月のために錆のために少し時間を持っおいたが、時間でこれを䞻匵しおいる私は基本的な圢質のデザむンは、これらの゜リュヌションに圱響を䞎えるず思いたす。 ここでも完党に自分の䞻匵をする時間があるずは思えないので、最初に少なくずもそれらすべおの完党な解決策を曞いおくれるこずを願っおいたす厳密正しい䜿甚法を匷制する、柔軟性は䞍可胜であるず誰かが私に間違っおいるこずを蚌明したす、および珟圚の特性で人間工孊的。 たたは、䞊郚のチェックボックスをオンにしたす。

Re @ Ericson2314のコメント

その芖点ず@alexcrichtonの䜕かを安定させたいずいう願望ずの察立に関連する質問は、最小限のむンタヌフェヌスを安定させるこずでどれだけの利益が埗られるかずいうこずだず思いたす。 特に、 Allocメ゜ッドを盎接呌び出す消費者はほずんどいないためほずんどのコレクションでさえ、おそらくBoxたたは他の同様のコンテナを䜿甚したす、本圓の問題は次のようになりたす。 Allocメ゜ッドを盎接呌び出しおいたせんか 正盎なずころ、私が考えるこずができる唯䞀の深刻なナヌスケヌスは、アロケヌタヌ倚型コレクションはるかに幅広いナヌザヌセットによっお䜿甚される可胜性が高いぞの道を開くこずですが、それは27336でブロックされおいるようです。解決されおいたす。 私が芋逃しおいる他の倧きな䜿甚䟋があるかもしれたせんが、その迅速な分析に基づいお、埌で最適ではないずわかるかもしれない蚭蚈に私たちを閉じ蟌めるずいう犠牲を払っお、わずかな利点しか持たないため、安定化から離れる傟向がありたす。

@joshlfを䜿甚するず、

うヌん良い点。 Allocを安定させるこずなく、グロヌバルアロケヌタの指定を安定させるこずは可胜でしょうか ぀たり、 Allocを実装するコヌドは䞍安定である必芁がありたすが、それはおそらく独自のクレヌトにカプセル化され、そのアロケヌタヌをグロヌバルアロケヌタヌずしおマヌクするメカニズム自䜓は安定しおいたす。 それずも、安定/䞍安定ず安定コンパむラ/倜間コンパむラがどのように盞互䜜甚するかを誀解しおいたすか

ああ@joshlfは、 https //github.com/rust-lang/rust/issues/42774#issuecomment -317279035にあるように、27336が気を散らすものであるこずを芚えおおいお他の問題に遭遇するだろうず確信しおいたす---存圚する特性の問題。それが私が今それに぀いおの䜜業を開始するために働きたい理由です。 27336以降の予枬される先物に぀いお議論するよりも、すべおの人が芋るこずができるようになったら、これらの問題に぀いお議論する方がはるかに簡単です。

@joshlfただし、グロヌバルアロケヌタを定矩するクレヌトを安定したコンパむラでコンパむルするこずはできたせん。

@sfacklerああ、そうだ、私が恐れおいた誀解があるP

usizeは割り圓おられた远加サむズのように芁求された割り圓おのサむズではexcessではなく、 totalため、名前Excess(ptr, usize)は少し混乱したす。割り圓おのtotalサむズ。

IMO Total 、 Real 、 Usable 、たたはサむズが割り圓おの合蚈サむズたたは実際のサむズであるこずを瀺す名前は、私が芋぀けた「超過」よりも優れおいたす誀解を招く。 同じこずが_excessメ゜ッドにも圓おはたりたす。

䞊蚘の@gnzlbgに同意したす。プレヌンなptr、usizeタプルで十分だず思いたす。

ただし、 Excessは、最初のパスで安定化するこずは提案されおいないこずに泚意しおください。

懞念を持っおいる人がいるredditに関する議論のためにこのスレッドを投皿したした https 

今日@ rust-lang / libsずさらに話し合った埌、安定化の提案にいく぀かの調敎を加えたいず思いたす。

  • 安定化されたメ゜ッドのセットにalloc_zeroedを远加したす。それ以倖の堎合は、 allocず同じシグネチャを持ちたす。
  • extern { type void; }サポヌトを䜿甚しおAPIで*mut u8を*mut voidし、 @ dtolnayの懞念を解決し、゚コシステム党䜓でc_voidを統合する方法を提䟛したす。
  • allocの戻り倀の型を*mut voidに倉曎し、 ResultずError削陀したす

おそらく最も論議を呌んでいるのは最埌の点なので、それに぀いおも詳しく説明したいず思いたす。 これは今日のlibsチヌムずの話し合いから生たれたもので、特にa ResultベヌスのむンタヌフェヌスのABIの効率がポむンタヌを返すものよりも䜎く、b今日の「本番」アロケヌタヌがほずんどないこずを䞭心に展開されたした「これはただOOM'd」以䞊のものを孊ぶ胜力を提䟛したす。 パフォヌマンスのために、ほずんどの堎合、むンラむン化などで玙に曞くこずができたすが、 Errorは䜙分なペむロヌドであり、最䞋局で削陀するのは困難です。

゚ラヌのペむロヌドを返すための考え方は、アロケヌタヌが実装固有のむントロスペクションを提䟛しお、割り圓おが倱敗した理由を知るこずができるずいうこずです。そうでない堎合、ほずんどすべおのコンシュヌマヌは、割り圓おが成功したか倱敗したかを知るだけで枈みたす。 さらに、これは実際にはそれほど頻繁に呌び出されない非垞に䜎レベルのAPIであるこずが意図されおいたす代わりに、物事をうたくたずめる型付きAPIを代わりに呌び出す必芁がありたす。 その意味で、この堎所で最も䜿いやすく人間工孊に基づいたAPIを䜿甚するこずは重芁ではありたせんが、パフォヌマンスを犠牲にするこずなくナヌスケヌスを有効にするこずがより重芁です。

*mut u8の䞻な利点は、バむトオフセットで.offsetを䜿甚するず非垞に䟿利なこずです。

libsミヌティングでは、 T: Sizedに察しお定矩されおいる既存のoffsetず競合しないimpl *mut void { fn offset }も提案したした。 byte_offsetたす。

*mut voidおよびbyte_offsetを䜿甚する堎合*mut void +1。 externタむプ機胜の安定化に問題が発生するのでしょうか、それずも定矩のみが䞍安定でありliballocは内郚で䞍安定なこずを実行できる、䜿甚ではないためたずえば、 let a: *mut void = ... isn、その問題を回避できたすか䞍安定ではない

はい、externタむプの安定化をブロックする必芁はありたせん。 externタむプのサポヌトが削陀された堎合でも、これに察しお定矩するvoidは、垞に魔法のタむプの最悪のケヌスになる可胜性がありたす。

AllocずDeallocを別々の特性にするべきかどうかに぀いお、libs䌚議でさらに議論がありたしたか

特に觊れたせんでしたが、特にやむを埗ない理由がない限り、先行技術から逞脱するべきではないず䞀般的に感じおいたした。 特に、C ++のアロケヌタヌの抂念には同様の分割はありたせん。

この堎合、それが適切な比范であるかどうかはわかりたせん。 C ++では、すべおが明瀺的に解攟されるため、独自のアロケヌタヌのコピヌたたは参照を栌玍する必芁があるBox盞圓するものはありたせん。 それが私たちにずっお倧きなサむズの爆発を匕き起こす原因です。

@joshlf unique_ptrはBoxに盞圓し、 vectorはVecに盞圓し、 unordered_mapはHashMap盞圓したす

@cramertjああ、興味深いこずに、私はコレクションの皮類だけを芋おいたした。 その時はそれがやるべきこずのようです。 埌でブランケットimplを介しおい぀でも远加できたすが、それを回避する方がおそらくクリヌンです。

包括的実装アプロヌチは、実際にはよりクリヌンな堎合がありたす。

pub trait Dealloc {
    fn dealloc(&self, ptr: *mut void, layout: Layout);
}

impl<T> Dealloc for T
where
    T: Alloc
{
    fn dealloc(&self, ptr: *mut void, layout: Layout) {
        <T as Alloc>::dealloc(self, ptr, layout)
    }
}

ほずんどのナヌスケヌスで心配する必芁のある特性が1぀少なくなりたす。

  • allocの戻り倀の型を* mut voidに倉曎し、結果ず゚ラヌを削陀したす

おそらく最も論議を呌んでいるのは最埌の点なので、それに぀いおも詳しく説明したいず思いたす。 これは今日のlibsチヌムずの話し合いから生たれたもので、特にa結果ベヌスのむンタヌフェヌスのABIの効率がポむンタヌを返すむンタヌフェヌスよりも䜎く、b今日の「本番」アロケヌタヌが孊習機胜を提䟛しおいないこずを䞭心に展開されたした。 「これはただOOM'd」以䞊のもの。 パフォヌマンスのために、ほずんどの堎合、むンラむン化などを䜿甚しお玙で芆うこずができたすが、゚ラヌは、最䞋局で削陀するのが難しい䜙分なペむロヌドであるこずに倉わりはありたせん。

これにより、nullをチェックせずに返されたポむンタを非垞に簡単に䜿甚できるようになるのではないかず心配しおいたす。 Result<NonZeroPtr<void>, AllocErr>を返し、 AllocErrれロサむズにするこずで、このリスクを远加せずにオヌバヌヘッドを取り陀くこずもできるようです。

 NonZeroPtrは、https//github.com/rust-lang/rust/issues/27730#issuecomment-316236397で提案されおいるように、 ptr::Sharedずptr::Uniqueをマヌゞしたものです。

@SimonSapinのようなResult<NonZeroPtr<void>, AllocErr>ようなものは、安定化するために3぀のタむプを必芁ずしたす。これらはすべお真新しいものであり、歎史的に安定化のためにかなり苊しんでいるものもありたす。 voidようなものは必須ではなく、私の意芋では持っおおくず䟿利です。

「nullをチェックせずに簡単に䜿甚できる」こずに同意したすが、これも非垞に䜎レベルのAPIであり、頻繁に䜿甚するこずを意図しおいないため、呌び出し元の人間工孊に合わせお最適化する必芁はないず思いたす。

たた、 Result<NonZeroPtr<void>, AllocErr>ようなより耇雑な戻り倀の型を持぀可胜性のある䜎レベルのalloc䞊に、 alloc_oneような高レベルの抜象化を構築するこずもできたす。

AllocErrは実際には圹に立たないこずに同意したすが、 Option<NonZeroPtr<void>>どうでしょうか。 オヌバヌヘッドなしで誀っお誀甚するこずが䞍可胜なAPIは、RustをCず区別するものの1぀であり、Cスタむルのnullポむンタヌに戻るこずは私にずっお䞀歩埌退したように感じたす。 「頻繁に䜿甚するこずを意図しおいない非垞に䜎レベルのAPI」であるず蚀うこずは、非垞に䜎レベルであたり䜿甚されおいないため、䞀般的でないマむクロコントロヌラヌアヌキテクチャのメモリの安党性を気にするべきではないず蚀うようなものです。

この関数の戻り倀の型に関係なく、アロケヌタずのすべおの察話には安党でないコヌドが含たれたす。 䜎レベルの割り圓おAPIは、戻り倀の型がOption<NonZeroPtr<void>>か*mut voidかに関係なく誀甚される可胜性がありたす。

特にAlloc::allocは、䜎レベルで頻繁に䜿甚されるこずを意図しおいないAPIです。 Alloc::alloc_one<T>やAlloc::alloc_array<T>ようなメ゜ッドは、より頻繁に䜿甚され、「より良い」戻り倀の型を持぀代替手段です。

ステヌトフルAllocErrorは䟡倀がありたせんが、Errorを実装し、 allocation failure Displayを持぀れロサむズの型があれば䟿利です。 私たちが行く堎合はNonZeroPtr<void>ルヌトを、私は芋Result<NonZeroPtr<void>, AllocError>よりも奜たしいずOption<NonZeroPtr<void>> 。

安定化を急ぐ理由 !! Result<NonZeroPtr<void>, AllocErr>は、クラむアントが䜿甚するのに間違いなく優れおいたす。これが「非垞に䜎レベルのAPI」であり、優れおいる必芁はないずいうのは、気のめいるように野心的です。すべおのレベルのコヌドは、可胜な限り安党で保守可胜です。垞に線集されおいないしたがっお、人々の短期蚘憶にペヌゞングされおいないあいたいなコヌドはなおさらです

さらに、私が確かに望んでいる、ナヌザヌ䜜成のallocate-polymorphicコレクションがある堎合、それはアロケヌタヌを盎接䜿甚するかなり耇雑なコヌドのオヌプン量です。

再デロアクション、運甚䞊、ツリヌベヌスのコレクションごずに1回だけアロアクタヌを参照/クロヌンしたいずほが確実に考えおいたす。 これは、砎棄される各カスタムアロケヌタヌボックスにアロケヌタヌを枡すこずを意味したす。 しかし、線圢型を䜿甚せずにRustでこれを行う最善の方法に぀いおは未解決の問題です。 以前のコメントずは異なり、このためのコレクションの実装には安党でないコヌドが含たれおいおも問題ありたせん。理想的なナヌスケヌスでは、分割アロケヌタヌずデアロケヌタヌの特性の実装ではなく、 Boxの実装が倉曎されるためです。 ぀たり、盎線性を劚げるこずなく、安定した進歩を遂げるこずができたす。

@sfacklerデアロケヌタヌをアロケヌタヌに接続するいく぀かの関連タむプが必芁だず思いたす。 それらを埌付けするこずは䞍可胜かもしれたせん。

@ Ericson2314人々は実䞖界の実物にアロケヌタヌを䜿甚したいので、安定させるための「ラッシュ」がありたす。 これは科孊プロゞェクトではありたせん。

その関連するタむプは䜕に䜿甚されたすか

@sfacklerの人々はただ毎晩ピン留めするこずができたす/そしおこの皮の高床な機胜を気にするタむプの人々はそれを快適に行うべきです。 [問題が䞍安定なrustcず䞍安定なRustである堎合、それはポリシヌの修正が必芁な別の問題です。]逆に、新しい2.0 stdで゚コシステムを分割したい堎合を陀いお、お粗末なAPIをベむクするこずは私たちを氞遠に劚げたす。

関連するタむプは、デアロケヌタヌをアロケヌタヌに関連付けたす。 これが機胜するためには、それぞれが他のこずを知る必芁がありたす。 [正しいタむプの間違ったデアロケヌタヌを䜿甚するずいう問題はただありたすが、その解決策をリモヌトで提案した人は誰もいないこずを認めたす。]

人々が毎晩ピン留めできるのなら、なぜ私たちは安定したビルドを持っおいるのですか アロケヌタヌAPIず盎接察話しおいる人々のセットは、グロヌバルアロケヌタヌを眮き換えるなどしおそれらのAPIを利甚したい人々よりもはるかに少ないです。

デアロケヌタヌが関連するアロケヌタヌのタむプを知る必芁がある理由を瀺すコヌドを蚘述できたすか C ++のアロケヌタAPIが同様のマッピングを必芁ずしないのはなぜですか

人々が毎晩ピン留めできるのなら、なぜ私たちは安定したビルドを持っおいるのですか

蚀語の安定性を瀺すため。 このバヌゞョンのものに察しお䜜成したコヌドは決しお壊れたせん。 新しいコンパむラヌ。 非垞に悪いものが必芁な堎合は毎晩ピン留めしたす。その保蚌に倀する品質ず芋なされる機胜の最埌の反埩を埅぀䟡倀はありたせん。

アロケヌタヌAPIず盎接察話しおいる人々のセットは、グロヌバルアロケヌタヌを眮き換えるなどしおそれらのAPIを利甚したい人々よりもはるかに少ないです。

あはは これは、jemallocをツリヌから移動するためなどですか グロヌバルアロケヌタの遞択を可胜にするひどいハックを安定させるこずを提案した人は誰もいたせん。ヒヌプ自䜓を静的にするだけですか それずも私は提案を間違っお読んだのですか

グロヌバルアロケヌタの遞択を可胜にするひどいハックは安定化するこずが提案されおいたす。これは、jemallocをツリヌから移動できるようにするものの半分です。 この問題は残りの半分です。

#[global_allocator]属性の安定化 https 

うわぁ

@ Ericson2314グロヌバルアロケヌタを遞択するためのひどい方法は䜕だず思いたすか

https://github.com/rust-lang/rust/issues/27389#issuecomment-342285805で返信

提案は* mutvoidを䜿甚するように修正されたした。

@rfcbotが解決したした* mut u8

@rfcbotレビュヌ

IRC䞊でいく぀かの議論の埌、私たちは安定する぀もりNOT_ARCHIVEDの_doこずを理解した䞊で、これを承認しおいたすBox䞊の汎甚Alloc 、代わりにいく぀かのDeallocで圢質をここで@sfacklerによっお提案されおいるように、適切なブランケットimpl。 意図を誀解した堎合はお知らせください。

@cramertj明確にするために、Alloc定矩を砎らないようにするこずは可胜ですか

@joshlfうん、次のようになりたす https 

どのように指定したすDealloc䞎えるためにAlloc  私はこのようなものを想像したすか

pub unsafe trait Alloc {
    type Dealloc: Dealloc = Self;
    ...
}

それは私たちを厄介な領域WRThttps //github.com/rust-lang/rust/issues/29661に眮くず思い

ええ、私はのほか持぀方法ないず思うDeallocの既存の定矩ずの䞋䜍互換性がAllocデフォルトを持たずに぀たり、関連するタむプを持たないが。

アロケヌタヌに察応するデアロケヌタヌを自動的に取埗できるようにする堎合は、関連付けられたタむプだけでなく、デアロケヌタヌ倀を生成する関数が必芁になりたす。

しかし、これは将来、 Alloc別のサブトレむトに添付されたもので凊理できるず思いたす。

@sfackler理解できたせん。 あなたのデザむンの䞋でBox::newの眲名を曞き出すこずができたすか

これは配眮構文ずそのすべおを無芖しおいたすが、それを行うこずができる1぀の方法は

pub struct Box<T, D>(NonZeroPtr<T>, D);

impl<T, D> Box<T, D>
where
    D: Dealloc
{
    fn new<A>(alloc: A, value: T) -> Box<T, D>
    where
        A: Alloc<Dealloc = D>
    {
        let ptr = alloc.alloc_one().unwrap_or_else(|_| alloc.oom());
        ptr::write(&value, ptr);
        let deallocator = alloc.deallocator();
        Box(ptr, deallocator)
    }
}

特に、タむプを知るだけでなく、実際にデアロケヌタヌのむンスタンスを生成できる必芁がありたす。 AllocもBoxをパラメヌタヌ化しお、代わりにA::Deallocを栌玍するこずもできたす。これは、型掚論に圹立぀堎合がありたす。 Deallocずdeallocatorを別のトレむトに移動するこずで、この安定化の埌にこれを機胜させるこずができたす。

pub trait SplitAlloc: Alloc {
    type Dealloc;

    fn deallocator(&self) -> Self::Dealloc;
}

しかし、 Dropの実装はどのようになりたすか

impl<T, D> Drop for Box<T, D>
where
    D: Dealloc
{
    fn drop(&mut self) {
        unsafe {
            ptr::drop_in_place(self.0);
            self.1.dealloc_one(self.0);
        }
    }
}

しかし、最初にAllocを安定させるず仮定するず、すべおのAllocがDeallocを実装するわけではありたせん。 そしお、私はimplの専門化はただ道のりだず思いたしたか ぀たり、理論的には次のようなこずをしたいのですが、ただうたくいかないず思いたすか

impl<T, D> Drop for Box<T, D> where D: Dealloc { ... }
impl<T, A> Drop for Box<T, A> where A: Alloc { ... }

どちらかずいえば、

default impl<T> SplitAlloc for T
where
    T: Alloc { ... }

しかし、それは本圓に必芁だずは思いたせん。 カスタムアロケヌタずグロヌバルアロケヌタのナヌスケヌスは十分に異なるため、それらの間に倧量の重耇があるずは思いたせん。

私はそれがうたくいくず思いたす。 しかし、私には、 Deallocすぐに䜿甚しお、より単玔なむンタヌフェむスを䜿甚できるようにする方がはるかにクリヌンに思えたす。 すでにAlloc実装しおいる既存のコヌドを倉曎する必芁のない、非垞にシンプルで議論の䜙地のないむンタヌフェむスを䜜成できるず思いたす。

unsafe trait Dealloc {
    fn dealloc(&mut self, ptr: *mut void, layout: Layout);
}

impl<T> Dealloc for T
where
    T: Alloc
{
    fn dealloc(&self, ptr: *mut void, layout: Layout) {
        <T as Alloc>::dealloc(self, ptr, layout)
    }
}

unsafe trait Alloc {
    type Dealloc: Dealloc = &mut Self;
    fn deallocator(&mut self) -> Self::Dealloc { self }
    ...
}

関連する型のデフォルトには問題がありたしたが

アロケヌタぞの倉曎可胜な参照であるDealloc 、それほど有甚ではないようです。䞀床に割り圓おるこずができるのは1぀だけですよね

関連する型のデフォルトには問題がありたしたが

ああ、関連する型のデフォルトは十分に離れおいるので、それらに頌るこずはできないず思いたす。

それでも、もっず簡単にするこずができたす。

unsafe trait Dealloc {
    fn dealloc(&mut self, ptr: *mut void, layout: Layout);
}

impl<T> Dealloc for T
where
    T: Alloc
{
    fn dealloc(&self, ptr: *mut void, layout: Layout) {
        <T as Alloc>::dealloc(self, ptr, layout)
    }
}

unsafe trait Alloc {
    type Dealloc: Dealloc;
    fn deallocator(&mut self) -> Self::Dealloc;
    ...
}

実装者にボむラヌプレヌトを少し曞くように芁求するだけです。

アロケヌタぞの倉曎可胜な参照であるDealloc 、それほど有甚ではないようです。䞀床に割り圓おるこずができるのは1぀だけですよね

ええ、良い点です。 あなたの他のコメントを考えるず、おそらくずにかく論点です。

deallocatorはself 、 &self 、たたは&mut self取る必芁がありたすか

おそらく&mut selfは、他の方法ず䞀貫性があるためです。

クロヌン状態などを必芁ずしないように、倀で自己を取るこずを奜むアロケヌタヌはありたすか

selfを倀で取埗する堎合の問題は、 Deallocを取埗しおから、割り圓おを続行できないこずです。

架空の「ワンショット」アロケヌタヌを考えおいたすが、それがどれだけ本物かはわかりたせん。

このようなアロケヌタは存圚する可胜性がありたすが、 selfを倀で取埗するには、_all_アロケヌタがそのように機胜する必芁があり、 deallocatorが呌び出された埌にアロケヌタが割り圓おを蚱可するこずはできたせん。

それを安定させるこずを考える前に、これのいく぀かがコレクションで実装され、䜿甚されるこずをただ望んでいたす。

あなたは思いたすhttps://github.com/rust-lang/rust/issues/27336かで議論のポむントhttps://github.com/rust-lang/rust/issues/32838#issuecomment -339066870は私たちができるようになりたすコレクションを進めたすか

タむプ゚むリアスアプロヌチがドキュメントの読みやすさに䞎える圱響が心配です。 進行を蚱可する非垞に冗長な方法は、タむプをラップするこずです。

pub struct Vec<T>(alloc::Vec<T, Heap>);

impl<T> Vec<T> {
    // forwarding impls for everything
}

苊痛だずは思いたすが、ここで説明しおいる倉曎は十分に倧きいため、alloc / deallocの分割特性を䜿甚しお進める堎合は、最初にstdで詊しおから、再FCPを実行する必芁がありたす。

このようなものが実装されるのを埅぀タむムラむンは䜕ですか

grow_in_placeメ゜ッドは、いかなる皮類の超過容量も返したせん。 珟圚、レむアりトを䜿甚しおusable_sizeを呌び出し、このレむアりトに_少なくずも_適合するように割り圓おを拡匵したすが、割り圓おがそのレむアりトを超えお拡匵された堎合、ナヌザヌは知る方法がありたせん。

alloc_excessおよびrealloc_excessに察するallocおよびreallocメ゜ッドの利点を理解するのに苊劎しおいたす。

アロケヌタは、割り圓おを実行するために適切なメモリブロックを芋぀ける必芁がありたす。これには、メモリブロックのサむズを知る必芁がありたす。 次にアロケヌタがポむンタを返すか、タプル「メモリブロックのポむンタずサむズ」がパフォヌマンスに枬定可胜な違いをもたらすこずはありたせん。

したがっお、 allocずreallocは、APIサヌフェスを増やすだけで、パフォヌマンスの䜎いコヌドの蚘述を促進しおいるようです。 なぜAPIにそれらがあるのですか 圌らの利点は䜕ですか


線集蚀い換えるず、APIで割り圓おられる可胜性のあるすべおの関数は、 Excessを返す必芁がありたす。これにより、基本的にすべおの_excessメ゜ッドが䞍芁になりたす。

過剰は、倧きくなる可胜性のある配列を含むナヌスケヌスでのみ興味深いものです。 たずえば、 BoxやBTreeMap 、圹に立たないか、関連性がありたせん。 超過分を蚈算するのにいくらかのコストがかかる可胜性があり、確かにもっず耇雑なAPIがあるので、超過容量を気にしないコヌドがそれを支払うこずを匷制されるべきではないように思えたす。

超過分を蚈算するには、いくらかのコストがかかる堎合がありたす。

䟋を挙げおいただけたすか メモリを割り圓おるこずはできるが、実際に割り圓おられおいるメモリの量がわからないアロケヌタはわかりたせん。たた、想像もできたせん Excessずは割り圓おられたメモリの実際の量です。名前を倉曎したす。

これが少し物議を醞すかもしれない唯䞀の䞀般的に䜿甚されるAlloc atorは、POSIX malloc 。これは、垞にExcess内郚で蚈算したすが、Cの䞀郚ずしお公開したせん。 API。 ただし、芁求されたサむズをExcessずしお返すこずは問題なく、移怍可胜で、単玔で、たったく費甚がかからず、POSIX mallocを䜿甚するすべおの人がずにかくすでに想定しおいるこずです。

jemallocず基本的に他のAlloc atorは、コストをかけずにExcessを返すAPIを提䟛するため、これらのアロケヌタヌの堎合、 Excess返すこずはれロです。コストも。

超過分を蚈算するのにいくらかのコストがかかる可胜性があり、確かにもっず耇雑なAPIがあるので、超過容量を気にしないコヌドがそれを支払うこずを匷制されるべきではないように思えたす。

珟圚、誰もがメモリを割り圓おるための2぀のAPIを持぀アロケヌタトレむトの䟡栌をすでに支払っおいたす。 1を構築するこずができたすしながらExcessの䞊に-less API Excess -full one`を、逆は真ではありたせん。 だから私はなぜそれがこのように行われないのだろうか

  • Alloc特性メ゜ッドは垞にExcess返したす
  • 1 Allocを䜿甚するのに十分泚意しおいるが、2䜿甚しないすべおのナヌザヌに察しお、 Allocメ゜ッドからExcessを削陀するExcessLessAlloc特性を远加したす。珟圚割り圓おられおいる実際のメモリ量に泚意しおください私にはニッチのように芋えたすが、そのようなAPIがあるず䟿利だず思いたす
  • ある日、誰かがExcessなしのメ゜ッドの高速パスを䜿甚しおAlloc atorを実装する方法を発芋した堎合、い぀でもExcessLessAllocカスタム実装を提䟛できたす。

FWIW Alloc䞊に必芁なものを実装できないため、このスレッドに再びアクセスしたした。 以前にgrow_in_place_excessが欠萜しおいるず述べたしたが、 alloc_zeroed_excessも欠萜しおいるためそしお誰が他に䜕を知っおいるか、再び行き詰たりたした。

ここでの安定化が、最初にExcess -fullAPIの安定化に焊点を合わせればもっず快適になりたす。 そのAPIがすべおの甚途で最も人間工孊的ではない堎合でも、そのようなAPIは少なくずもすべおの甚途を蚱可したす。これは、蚭蚈に欠陥がないこずを瀺すために必芁な条件です。

䟋を挙げおいただけたすか メモリを割り圓おるこずはできるが、実際に割り圓おられおいるメモリの量がわからないアロケヌタはわかりたせん。たた、想像もできたせん Excessずは割り圓おられたメモリの実際の量です。名前を倉曎したす。

今日のほずんどのアロケヌタはサむズクラスを䜿甚したす。各サむズクラスは特定の固定サむズのオブゞェクトのみを割り圓お、特定のサむズクラスに適合しない割り圓お芁求は、内郚に適合する最小サむズクラスに切り䞊げられたす。 このスキヌムでは、サむズクラスオブゞェクトの配列を䜜成しおからclasses[size / SIZE_QUANTUM].alloc()を実行するのが䞀般的です。 その䞖界では、どのサむズのクラスが䜿甚されおいるかを理解するには、远加の指瀺が必芁です。たずえば、 let excess = classes[size / SIZE_QUANTUM].size 。 それほど倚くはないかもしれたせんが、高性胜アロケヌタjemallocなどのパフォヌマンスは単䞀のクロックサむクルで枬定されるため、特にそのサむズが関数のリタヌンのチェヌンを通過する堎合は、意味のあるオヌバヌヘッドを衚す可胜性がありたす。

䟋を挙げおいただけたすか

少なくずもPRからalloc_jemallocに移行するず、 alloc_excessはallocよりも明らかに倚くのコヌドを実行しおいたす https 

このスキヌムでは、サむズクラスオブゞェクトの配列を䜜成しおからclasses [size / SIZE_QUANTUM] .allocを実行するのが䞀般的です。 その䞖界では、䜿甚されおいるサむズクラスを把握するには、远加の手順が必芁です。たずえば、excess = classes [size / SIZE_QUANTUM] .sizeずしたす。

だから私が正しく埓うかどうか芋おみたしょう

// This happens in both cases:
let size_class = classes[size / SIZE_QUANTUM];
let ptr = size_class.alloc(); 
// This would happen only if you need to return the size:
let size = size_class.size;
return (ptr, size);

それですか


少なくずもPRからalloc_jemallocに移行するず、alloc_excessはallocよりも明らかに倚くのコヌドを実行しおいたす。

そのPRはバグ修正パフォヌマンス修正ではありたせんでした。パフォヌマンスに関しおは、jemallocレむダヌの珟圚の状態に倚くの問題がありたすが、そのPRなので、少なくずも次のようになりたす。

  • nallocxは、GCCの意味でのconst関数、぀たり真の玔粋関数です。 これは、副䜜甚がなく、結果が匕数のみに䟝存し、グロヌバル状態にアクセスせず、匕数がポむンタヌではないこずを意味したすしたがっお、関数はグロヌバル状態にアクセスできず、それらをスロヌしたす。C/ C ++プログラムの堎合、LLVMはこれを䜿甚できたす。結果が䜿甚されない堎合に呌び出しを削陀するための情報。 AFAIK Rustは珟圚、FFIC関数をconst fnなどずしおマヌクするこずはできたせん。 したがっお、これは修正できる最初のこずであり、むンラむン化ず最適化が適切に機胜する限り、超過分を䜿甚しない堎合はrealloc_excessれロコストになりたす。
  • nallocxは、垞にmallocx内の敎列された割り圓おに察しお蚈算されたす。぀たり、すべおのコヌドはすでにそれを蚈算しおいたすが、 mallocxは結果を砎棄するため、ここでは実際に2回蚈算しおいたす。 、堎合によっおはnallocxはmallocx nallocxずほが同じくらい高䟡です...ブランチにこのようなもののベンチマヌクがあるjemallocatorのフォヌクがありたすが、これはアップストリヌムで修正する必芁がありたすこれを捚おないAPIを提䟛するこずによるjemalloc。 ただし、この修正は、珟圚Excessを䜿甚しおいるものにのみ圱響したす。
  • そしお、それは私たちが敎列フラグを2回蚈算しおいるずいう問題ですが、それはLLVMが私たちの偎で最適化できるものですそしお修正するのは簡単です。

そうです、それはより倚くのコヌドのように芋えたすが、この䜙分なコヌドは、実際に2回呌び出しおいるコヌドです。これは、最初に呌び出したずきに結果を砎棄したためです。 修正するこずは䞍可胜ではありたせんが、私はただこれを修正する時間を芋぀けおいたせん。


線集 @sfackler今日はなんずか時間をallocに関しおalloc_excess 「無料」にするこずができ、オヌバヌヘッドは玄1nsしかありたせんでした。 jemallocsの高速パス。 ファストパスに぀いおはあたり詳しく調べおいたせんが、これをさらに改善できる可胜性がありたす。 詳现はこちら https 

それですか

はい。

したがっお、これは修正できる最初のこずであり、むンラむン化ず最適化が適切に機胜する限り、超過分を䜿甚しない堎合はrealloc_excessのコストをれロにしたす。

グロヌバルアロケヌタずしお䜿甚する堎合、これをむンラむン化するこずはできたせん。

そのAPIがすべおの甚途で最も人間工孊的ではない堎合でも、そのようなAPIは少なくずもすべおの甚途を蚱可したす。これは、蚭蚈に欠陥がないこずを瀺すために必芁な条件です。

alloc_excessを呌び出すGithubには文字通りれロのコヌドがありたす。 これが非垞に重芁な機胜である堎合、なぜ誰もそれを䜿甚したこずがないのですか C ++の割り圓おAPIは、過剰な容量ぞのアクセスを提䟛したせん。 これらの機胜がパフォヌマンスを向䞊させるずいう実際の具䜓的な蚌拠があり、誰もが実際にそれらを䜿甚するのに十分気を配っおいる堎合、䞋䜍互換性のある方法で将来これらの機胜を远加/安定化するこずは非垞に簡単に思えたす。

グロヌバルアロケヌタずしお䜿甚する堎合、これをむンラむン化するこずはできたせん。

jemallocようなグロヌバルアロケヌタはこれに䟝存しおいるため、少なくずもLTOビルドでは、これを解決する必芁がありたす。 nallocxは、_蚭蚈による_方法であり、最初の掚奚事項です。 jemallocの開発者は、 alloc_excessパフォヌマンスに関しお、これらの呌び出しをむンラむン化する必芁があり、C属性を適切に䌝播しお、コンパむラヌが呌び出しサむトからnallocx呌び出しを削陀するようにしたした。 CおよびC ++コンパむラず同様に、 Excess䜿甚したす。

それができない堎合でも、 jemalloc APIにパッチを適甚するこずで、 Excess APIをれロコストにするこずができたすこのようなパッチの初期実装は、rust-lang /にありたす。 jemallocフォヌク。 そのAPIを自分で維持するこずも、アップストリヌムに配眮するこずもできたすが、アップストリヌムに配眮するには、これらの他の蚀語がこれらの最適化を実行でき、Rustが実行できない理由に぀いお適切なケヌスを䜜成する必芁がありたす。 たたは、この新しいAPIは、 Excess必芁ずするナヌザヌにずっお、 mallocx + nallocxよりも倧幅に高速であるなどの別の匕数が必芁です。

これが非垞に重芁な機胜である堎合、なぜ誰もそれを䜿甚したこずがないのですか

それは良い質問です。 std::Vecは、 Excess APIを䜿甚するためのポスタヌの子ですが、珟圚は䜿甚しおいたせん。以前のコメントはすべお、「これずそれはExcessから欠萜しおいたす。 API」は私がVecそれを䜿わせようずしおいたした。 Excess API

  • Excessをたったく返さなかった https 
  • grow_in_place_excessやalloc_zeroed_excessなどの機胜が䞍足しおいたす。
  • FFIでC属性を正しく䌝播できない https 
  • ...ここで終わるずは思えたせん

なぜ誰もこのAPIを䜿甚しおいないのかわかりたせん。 しかし、 stdラむブラリでさえ、それが最適なデヌタ構造 Vec に䜿甚できないこずを考えるず、掚枬しなければならない堎合、䞻な理由は次のずおりです。このAPIは珟圚壊れおいたす。

さらに掚枬しなければならない堎合、䞻に単䞀のstdコレクションが䜿甚しおいないためこのAPIが最初にテストされるず予想される堎所、このAPIを蚭蚈した人でさえ䜿甚しおいないず蚀えたす。たた、 _excessずExcessどこでも䜿甚しおusable_size / allocation_sizeを意味するのは、プログラミングが非垞に混乱し、煩わしいためです。

これはおそらく、 Excess少ないAPIにより倚くの䜜業が費やされ、2぀のAPIがある堎合、それらの同期を維持するのが難しく、ナヌザヌが䞡方を芋぀けおどちらを䜿甚するかを知るのが難しいためです。そしお最埌に、ナヌザヌが正しいこずをするよりも䟿利さを奜むのは難しいです。

぀たり、競合するAPIが2぀あり、䜜業の100を䞀方の改善に、0を他方の改善に費やした堎合、䞀方が実際に倧幅に機胜しおいるずいう結論に達するのは圓然のこずです。他よりも優れおいたす。

私の知る限り、Githubでのjemallocテスト以倖のnallocxぞの呌び出しは2぀だけです。

https://github.com/facebook/folly/blob/f2925b23df8d85ebca72d62a69f1282528c086de/folly/detail/ThreadLocalDetail.cpp#L182
https://github.com/louishust/mysql5.6.14_tokudb/blob/4897660dee3e8e340a1e6c8c597f3b2b7420654a/storage/tokudb/ft-index/ftcxx/malloc_utils.hpp#L91

どちらも珟圚のalloc_excess APIに䌌おいたせんが、スタンドアロンで䜿甚されお、割り圓おサむズが䜜成される前に蚈算されたす。

Apache Arrowは、実装でnallocxを䜿甚するこずを怜蚎したしたが、うたく機胜しないこずがわかりたした。

https://issues.apache.org/jira/browse/ARROW-464

これらは基本的に私が芋぀けるこずができるnallocxぞの唯䞀の参照です。 アロケヌタヌAPIの最初の実装がそのようなあいたいな機胜をサポヌトするこずが重芁なのはなぜですか

私の知る限り、Githubでのjemallocテスト以倖のnallocxぞの呌び出しは2぀だけです。

私の頭のおっぺんから、少なくずもfacebookのベクタヌタむプがfacebookのmalloc実装を介しおそれを䜿甚しおいるこずを知っおいたす mallocずfbvectorの成長ポリシヌ;これはfacebookのC ++のベクタヌの倧きな塊ですそしおたたChapelはそれを改善するために䜿甚したしたStringタむプのパフォヌマンスここず远跡の問題。 では、今日はGithubの最高の日ではなかったのでしょうか。

アロケヌタヌAPIの最初の実装がそのようなあいたいな機胜をサポヌトするこずが重芁なのはなぜですか

アロケヌタAPIの最初の実装では、この機胜をサポヌトする必芁はありたせん。

ただし、この機胜を適切にサポヌトするず、そのようなAPIの安定化がブロックされるはずです。

逆方向に远加できるのに、なぜ安定化をブロックする必芁があるのですか埌で互換性がありたすか

逆方向に远加できるのに、なぜ安定化をブロックする必芁があるのですか埌で互換性がありたすか

少なくずも私にずっおは、デザむンスペヌスの半分だけが十分に調査されおいるこずを意味したす。

APIの過剰に関連しない郚分は、過剰に関連する機胜の蚭蚈によっお圱響を受けるず思いたすか 私はその議論に䞭途半端にしか埓わなかったこずを認めたすが、それは私にはありそうもないようです。

このAPIを䜜成できない堎合

fn alloc(...) -> (*mut u8, usize) { 
   // worst case system API:
   let ptr = malloc(...);
   let excess = malloc_excess(...);
   (ptr, excess)
}
let (ptr, _) = alloc(...); // drop the excess

これず同じくらい効率的

fn alloc(...) -> *mut u8 { 
   // worst case system API:
   malloc(...)
}
let ptr = alloc(...);

それから私達はより倧きな問題を抱えおいたす。

APIの過剰に関連しない郚分は、過剰に関連する機胜の蚭蚈によっお圱響を受けるず思いたすか

そうです、私は、過剰なAPIが、過剰に関連しない機胜の蚭蚈に倧きな圱響を䞎えるこずを期埅しおいたす。それは完党に削陀されたす。

これにより、2぀のAPIが同期しおおらず、excess-apiの機胜がexcess-lessのAPIよりも少ないずいう珟圚の状況を防ぐこずができたす。 過剰なAPIの䞊に過剰な少ないAPIを構築するこずはできたすが、その逆は圓おはたりたせん。

Excessをドロップしたい人は、それをドロップする必芁がありたす。

明確にするために、䞋䜍互換性のある方法で事埌にalloc_excessメ゜ッドを远加する方法があれば、それで倧䞈倫ですか もちろん、 alloc_excessなしで安定させるずいうこずは、埌で远加するこずは重倧な倉曎になるこずを意味したす。私はただ尋ねおいるので、あなたの理由を理解しおいたす

@joshlfそれを行うのは非垞に簡単です。

bell䞊蚘のこれは珟圚、最終コメント期間に入っおいたす。 ベル

超過分をドロップしたい人はそれをドロップする必芁がありたす。

あるいは、過剰な容量を気にする0.01の人が別の方法を䜿甚できたす。

@sfacklerこれは、錆から2週間の䌑憩を取るこずで埗られるものです-デフォルトのメ゜ッドimplsを忘れおいたす:)

あるいは、過剰な容量を気にする0.01の人が別の方法を䜿甚できたす。

この番号はどこで入手できたすか

私のRustデヌタ構造はすべおメモリ内でフラットです。 それを実行できるこずが、私がRustを䜿甚する唯䞀の理由です。 すべおをボックス化できれば、別の蚀語を䜿甚するこずになりたす。 だから私はい぀もExcess 0.01%を気にしたせん、私はい぀もそれを気にしたす。

これはドメむン固有であり、他のドメむンではExcess気にしないこずは理解しおいたすが、Rustナヌザヌの0.01だけがこれを気にかけおいるずは思えたせん぀たり、倚くの人がVec䜿甚しおいたす String 、 Excess子のデヌタ構造です。

この数は、mallocを䜿甚するもののセットず比范しお、nallocxを䜿甚するものが合蚈で玄4぀あるずいう事実から埗おいたす。

@gnzlbg

最初から「正しく」実行した堎合、 fn alloc(layout) -> (ptr, excess)あり、 fn alloc(layout) -> ptrはたったくないこずを瀺唆しおいたすか それは私には明らかではないようです。 超過分が利甚できる堎合でも、 alloc_excess(layout).0ずしお実装されおいる堎合でも、超過分が問題にならないナヌスケヌスほずんどのツリヌ構造などには埌者のAPIを䜿甚するのが自然なようです。

@rkruppe

それは私には明らかではないようです。 超過が利甚可胜であっおも、alloc_excesslayout.0ずしお実装されおいる堎合でも、超過が問題にならないナヌスケヌスほずんどのツリヌ構造などに埌者のAPIを䜿甚するのは自然なこずのようです。

珟圚、excess-full APIは、excess-lessAPIの䞊に実装されおいたす。 超過のないアロケヌタにAllocを実装するには、ナヌザヌがalloc deallocメ゜ッドず

ただし、excess-fullアロケヌタにAllocを実装する堎合は、さらに倚くのメ゜ッドを提䟛する必芁がありたす少なくずも、 alloc_excessですが、 realloc_excessに入るず、これは倧きくなりたす。 alloc_zeroed_excess 、 grow_in_place_excess 、...。

逆の堎合、぀たり、excess-less APIをexcess-full APIの䞊に優れたものずしお実装し、 alloc_excessずdealloc実装するだけでサポヌトできたす。䞡方のタむプのアロケヌタ。

超過分を気にしない、たたは返送たたは照䌚できないナヌザヌは、入力サむズたたはレむアりトを返すこずができたすがこれは小さな䞍䟿です、超過分を凊理でき、凊理したいナヌザヌは実装する必芁はありたせん。これ以䞊の方法。


@sfackler

この数は、mallocを䜿甚するもののセットず比范しお、nallocxを䜿甚するものが合蚈で玄4぀あるずいう事実から埗おいたす。

Rust゚コシステムでの_excess䜿甚に関するこれらの事実を考えるず

  • 錆びた生態系で合蚈0個が_excessを䜿甚
  • ruststdラむブラリで合蚈0個が_excessしおいたす
  • VecずStringさえ、錆びたstdラむブラリで_excess APIを適切に䜿甚できたせん
  • _excess APIは䞍安定で、excess-less APIず同期しおおらず、ごく最近たでバグがありたした excessをたったく返さなかった...

    そしお、他の蚀語での_excessの䜿甚法に関するこれらの事実を考えるず

  • jemallocのAPIは、䞋䜍互換性のため、CたたはC ++プログラムではネむティブにサポヌトされおいたせん。

  • jemallocの過剰なAPIを䜿甚したいCおよびC ++プログラムは、次の方法でそれを䜿甚するために邪魔にならないようにする必芁がありたす。

    • システムアロケヌタヌからjemallocたたはtcmallocぞのオプトアりト

    • 蚀語の暙準ラむブラリを再実装したすC ++の堎合、互換性のない暙準ラむブラリを実装したす

    • この互換性のない暙準ラむブラリの䞊にスタック党䜓を曞き蟌みたす

  • 䞀郚のコミュニティFirefoxはこれを䜿甚し、FacebookはC ++暙準ラむブラリのコレクションを再実装しお䜿甚できるようにしたす...は、ただ䜿甚できたせん。

これらの2぀の議論は私にはもっずもらしく芋えたす

  • stdのexcess APIは䜿甚できないため、 stdラむブラリは䜿甚できたせん。したがっお、誰も䜿甚できたせん。そのため、Rust゚コシステムでは䞀床も䜿甚されたせん。 。
  • CずC ++では、このAPIを䜿甚するこずはほが䞍可胜ですが、人的資源を䌎う倧芏暡なプロゞェクトでは、このAPIを䜿甚するのに非垞に長い時間がかかりたす。したがっお、少なくずも䞀郚の朜圚的に小さなコミュニティは、このAPIを気にかけおいたす。

あなたの議論

  • _excess APIを䜿甚しおいる人はいないため、気にする人は0.01にすぎたせん。

ではない。

@alexcrichton -> Result<*mut u8, AllocErr>から-> *mut voidに切り替えるずいう決定は、アロケヌタヌRFCの最初の開発に埓った人々にずっお倧きな驚きずなるかもしれたせん。

私は同意しおいないあなたが䜜るのポむントが、それにもかかわらず、人々のかなりの数は、の「重weightness」ず䞀緒に暮らすに喜んであったであろうように思えたResult nullでは䞍足しおいる可胜性の増加を介しお戻り倀を確認しおください。

  • @alexcrichtonのように、コンパむラのトリックを介しお䜕らかの方法でそれらに察凊できるず想定しおいるため、ABIによっお課せられる実行時効率の問題を無芖しおいたす。

その遅い倉曎自䜓の可芖性を高める方法はありたすか

1぀の方法頭のおっぺんから Allocatorがただ䞍安定な状態で、PR自䜓のマスタヌブランチで眲名を倉曎したす。 そしお、誰がPRに䞍満を蚀っおいるのかそしお誰が祝っおいるのかを芋おください。

  • これは手に負えないですか 定矩䞊、このような倉曎を安定化ず組み合わせるよりも手間がかからないようです...

*mut voidを返すか、 Result<*mut void, AllocErr>を返すかに぀いお説明したように、「高レベル」ず「䜎レベル」のアロケヌタ特性を分離するずいう考えを再怜蚎する必芁がある可胜性がありたす。アロケヌタヌRFCのテむクIIで。

明らかに、 *mut void戻り倀に深刻な異議がある堎合は、fcpbotを介しお懞念事項ずしお提出したす。しかし、珟時点では、おそらく、libsチヌムの刀断をかなり信頌しおいたす。このアロケヌタヌサガの疲劎による郚分もありたす。

@pnkfelix

-> Result<*mut u8, AllocErr>から-> *mut voidに切り替えるずいう決定は、アロケヌタヌRFCの最初の開発に埓った人々にずっお倧きな驚きずなるかもしれたせん。

埌者は、説明したように、私たちが衚珟したい唯䞀の゚ラヌはOOMであるこずを意味したす。 したがっお、゚ラヌをチェックするための偶発的な倱敗に察する保護の利点をただ持っおいる、わずかに軜量な䞭間は-> Option<*mut void>です。

@gnzlbg

stdの䜙分なAPIは䜿甚できないため、stdラむブラリは䜿甚できたせん。したがっお、誰も䜿甚できたせん。そのため、Rust゚コシステムでは䞀床も䜿甚されたせん。

次に、それを修正したす。

@pnkfelix

mut voidを返すか、

高レベルAPIがalloc_one 、 alloc_arrayなどずしおAlloc自䜓に含たれるこずを陀いお、これらは基本的に私たちの考えalloc_array 。拡匵機胜ずしお最初に゚コシステムで開発させるこずもできたす。人々がどのAPIに収束するかを確認するための特性。

@pnkfelix

レむアりトにコピヌではなくクロヌンのみを実装させた理由は、レむアりトタむプに構造を远加する可胜性を残したかったからです。 特に、レむアりトがそれを構築するために䜿甚される任意の型構造たずえば、構造䜓の16配列{xu8、y[char; 215]}を远跡しようずするこずにただ興味がありたす。珟圚のコンテンツがどのタむプから構成されおいるかをレポヌトするむンストルメンテヌションルヌチンを公開するオプション。

これはどこかで実隓されたしたか

@sfackler私はすでにそのほずんどを実行しおおり、すべおを耇補されたAPIで実行できたす超過なし+ _excessメ゜ッド。 珟圚、2぀のAPIがあり、完党な_excess APIがなくおも問題ありたせん。

ただ少し心配しおいるのは、アロケヌタを今すぐ実装するにはalloc + deallocを実装する必芁があるずいうこずだけですが、 alloc_excess + deallocも同様に機胜するはずです。 alloc alloc_excess埌で


jemallocatorはAlloc 2回実装したす Jemallocず&Jemalloc 。ここで、䞀郚のmethodのJemalloc実装はメ゜ッド呌び出しを&Jemalloc実装に転送する(&*self).method(...) 。 これは、 JemallocのAlloc䞡方の実装を手動で同期させる必芁があるこずを意味したす。 &/_実装で異なる動䜜をするこずが悲劇的であるかどうかは、私にはわかりたせん。


実際にAlloc特性を䜿っお人々が実際に䜕をしおいるのかを知るのは非垞に難しいず思いたした。 それを䜿甚しおいるこずがわかった唯䞀のプロゞェクトは、ずにかく毎晩䜿甚し続けサヌボ、レドックス、グロヌバルアロケヌタヌを倉曎するためにのみ䜿甚しおいたす。 それをコレクションタむプのパラメヌタずしお䜿甚するプロゞェクトが芋぀からなかったのはずおも心配ですたぶん私は運が悪かっただけで、いく぀かありたすか。 私は特に、 Vecようなタむプの䞊にSmallVecずArrayVecを実装する䟋を探しおいたした std::VecはAllocがないため Vecが異なるAlloc atorを䜿甚がどのように機胜するのか疑問に思っおいたした同じこずがおそらくBoxクロヌン䜜成にも圓おはたりたす異なるAlloc sのBox es。 これらの実装がどこかにどのように芋えるかの䟋はありたすか

私が芋぀けた、それを䜿甚しおいる唯䞀のプロゞェクトは、ずにかく毎晩䜿甚し続ける぀もりですサヌボ、レドックス

䟡倀があるものずしお、Servoは可胜な限り䞍安定な機胜から移行しようずしおいたす https 

これも鶏が先か卵が先かずいう問題です。 倚くのプロゞェクトはただ䞍安定なため、 Allocただ䜿甚しおいたせん。

そもそもなぜ_excessAPIを完党に補完する必芁があるのか​​は私にはよくわかりたせん。 これらは元々、jemallocの実隓的な* allocm APIを反映するために存圚しおいたしたが、APIサヌフェス党䜓を耇補しないために、数幎前に4.0で削陀されたした。 私たちは圌らの先導に埓うこずができたようですか

埌でalloc_excessに関しおallocにデフォルトの実装を䞎えるこずは可胜でしょうか、それずも䞍可胜であるか、重倧な倉曎でしょうか

alloc_excessに関しおallocデフォルトの実装を远加できたすが、 alloc_excessはallocに関しおデフォルトの実装が必芁です。 䞀方たたは䞡方を実装すればすべお正垞に機胜したすが、どちらも実装しないず、コヌドはコンパむルされたすが、無限に再垰したす。 これは以前に発生したこずがありおそらくRand 、これらの関数の少なくずも1぀を実装する必芁があるず蚀うこずができたすが、どちらでもかたいたせん。

それをコレクションタむプのパラメヌタずしお䜿甚するプロゞェクトが芋぀からなかったのはずおも心配ですたぶん私は運が悪かっただけで、いく぀かありたすか。

私はそれをしおいる人を知りたせん。

私が芋぀けた、それを䜿甚しおいる唯䞀のプロゞェクトは、ずにかく毎晩䜿甚し続ける぀もりですサヌボ、レドックス

これが前進するのを劚げる倧きなこずの1぀は、stdlibコレクションがパラメトリックアロケヌタヌをただサポヌトしおいないこずです。 ほずんどの倖郚コレクションは内郚のもの Box 、 Vecなどを䜿甚するため、これは他のほずんどのクレヌトもほずんど排陀したす。

私が芋぀けた、それを䜿甚しおいる唯䞀のプロゞェクトは、ずにかく毎晩䜿甚し続ける぀もりですサヌボ、レドックス

これが前進するのを劚げる倧きなこずの1぀は、stdlibコレクションがパラメトリックアロケヌタヌをただサポヌトしおいないこずです。 ほずんどの倖郚コレクションは内郚のものBox、Vecなどを䜿甚するため、これは他のほずんどのクレヌトもほずんど排陀したす。

これは私にも圓おはたりたす-私はおもちゃのカヌネルを持っおいたす、そしおもし私がVec<T, A>を䜿うこずができれば、代わりに私は内郚で倉曎可胜なグロヌバルアロケヌタヌファサヌドを持たなければなりたせん。

@remexreデヌタ構造をパラメヌタ化しお、

内郚的に倉曎可胜なグロヌバル状態はただ存圚するず思いたすが、グロヌバルset_allocator関数を䜿甚するよりも、メモリが完党にマップされるたでグロヌバルアロケヌタヌを䜿甚できないように蚭定する方がはるかに安党だず感じたす。


線集私が質問に答えなかったこずに気づきたした。 今、私は次のようなものを持っおいたす

struct BumpAllocator{ ... }
struct RealAllocator{ ... }
struct LinkedAllocator<A: 'static + AreaAllocator> {
    head: Mutex<Option<Cons<A>>>,
}
#[global_allocator]
static KERNEL_ALLOCATOR: LinkedAllocator<&'static mut (AreaAllocator + Send + Sync)> =
    LinkedAllocator::new();

ここで、 AreaAllocatorは、アロケヌタヌが割り圓お先のアドレス範囲に関しお誀っお「オヌバヌラップ」しおいないこずを実行時に確認できる特性です。 BumpAllocatorは、メモリの残りの郚分をマッピングしおRealAllocatorを䜜成するずきのスクラッチスペヌスずしお、非垞に早い段階でのみ䜿甚されたす。

理想的には、 Mutex<Option<RealAllocator>> たたは「挿入専甚」にするラッパヌを唯䞀のアロケヌタヌにし、早期に割り圓おられたすべおのものをアヌリヌブヌトBumpAllocatorでパラメヌタヌ化するようにしたす。

@sfackler

そもそもなぜ_excessAPIを完党に補完する必芁があるのか​​は私にはよくわかりたせん。 これらは元々、jemallocの実隓的な* allocm APIを反映するために存圚しおいたしたが、APIサヌフェス党䜓を耇補しないために、数幎前に4.0で削陀されたした。 私たちは圌らの先導に埓うこずができたようですか

珟圚、 shrink_in_placeはxallocxを呌び出し、実際の割り圓おサむズを返したす。 shrink_in_place_excessは存圚しないため、このサむズは砎棄され、ナヌザヌはnallocxを呌び出しお再蚈算する必芁がありたす。そのコストは、割り圓おの倧きさによっお異なりたす。

したがっお、すでに䜿甚しおいる少なくずもいく぀かのjemalloc割り圓お関数は、䜿甚可胜なサむズを返したすが、珟圚のAPIではそれを䜿甚できたせん。

@remexre

私がおもちゃのカヌネルで䜜業しおいたずき、グロヌバルアロケヌタヌを避けお、アロケヌタヌがセットアップされるたで割り圓おが行われないようにするこずも私の目暙でした。 私が䞀人ではないず聞いおうれしいです

デフォルトのグロヌバルアロケヌタのHeapずいう単語は奜きではありたせん。 なぜDefaultないのですか

もう1぀の明確化のポむント RFC 1974は、これらすべおのものをstd::allocいたすが、珟圚はstd::heapたす。 安定化のためにどの堎所が提案されおいたすか

@jethrogb 「ヒヌプ」は、「mallocがあなたにポむンタを䞎えるもの」のかなり暙準的な甚語です-この甚語に察するあなたの懞念は䜕ですか

@sfackler

「mallocがあなたにポむンタを䞎えるこず」

私の頭の䞭を陀いお、それがSystemです。

確かに。 Globalは別の名前ですが、倚分 #[global_allocator]を䜿甚しお遞択するため。

耇数のヒヌプアロケヌタヌが存圚する可胜性がありたす䟋libcおよび接頭蟞jemalloc。 std::heap::Heap名前をstd::heap::Default 、 #[global_allocator]名前を#[default_allocator]どうですか

他に指定しない堎合おそらくVecがアロケヌタの远加の型パラメヌタ/フィヌルドを取埗する堎合に埗られるものであるずいう事実は、「per」がないずいう事実よりも重芁です。 -むンスタンス」状態たたは実際にはむンスタンス。

これで最終コメント期間が終了したした。

FCPに関しおは、安定化のために提案されたAPIサブセットの甚途は非垞に限られおいるず思いたす。 たずえば、 jemallocatorクレヌトはサポヌトしおいたせん。

どのように jemallocatorは、機胜フラグの背埌にある䞍安定なメ゜ッドのいく぀かの実装にフラグを立おる必芁があるかもしれたせんが、それだけです。

安定したRustのjemallocatorがje_rallocx呌び出しおAlloc::reallocなどを実装できないが、デフォルトのalloc + copy + dealloc implに䟝存する必芁がある堎合、それは暙準ラむブラリのalloc_jemallocクレヌトIMO。

確かに、コンパむルするものを入手するこずはできたすが、それは特に䟿利なこずではありたせん。

どうしお C ++のアロケヌタヌAPIには、reallocの抂念がたったくなく、蚀語が機胜しなくなったようには芋えたせん。 それは明らかに理想的ではありたせんが、なぜそれが受け入れられないのか理解できたせん。

C ++移動コンストラクタヌは任意のコヌドを実行できるため、C ++コレクションは通垞reallocを䜿甚したせん。これは、reallocが圹に立たないためではありたせん。

たた、比范はC ++ではなく、jemallocサポヌトが組み蟌たれた珟圚のRust暙準ラむブラリずの比范です。 Alloc APIのこのサブセットのみを䜿甚しお、暙準倖のアロケヌタヌに切り替えるず、リグレッションが発生したす。

そしおreallocはその䞀䟋です。 jemallocatorは珟圚、 alloc_zeroed 、 alloc_excess 、 usable_size 、 grow_in_placeなども実装しおいたす。

alloc_zeroedは安定化するように提案されおいたす。 私が知る限りアップスレッドを参照、 alloc_excess䜿甚は文字通りれロです。 デフォルトの実装にフォヌルバックした堎合にリグレッションを起こすコヌドをいく぀か瀺しおいただけたせんか。

しかし、もっず䞀般的には、これがこれらのAPIの䞀郚を安定させるこずに反察する議論である理由がわかりたせん。 jemallocatorを䜿甚したくない堎合は、匕き続き䜿甚しないでください。

Layout::array<T>() const fnにするこずはできたすか

パニックになる可胜性があるので、珟時点ではありたせん。

パニックになる可胜性があるので、珟時点ではありたせん。

なるほど... const fn Layout::array_elem<T>()で解決したす。これは、パニックにならないLayout::<T>::repeat(1).0盞圓したす。

@mzabaluevあなたが説明しおいるこずはLayout::new<T>()ず同等だず思いたす。 珟圚パニックになる可胜性がありたすが、それはLayout::from_size_align 、次に.unwrap()を䜿甚しお実装されおいるためであり、別の方法で実行できるず思いたす。

@joshlfこの構造䜓のサむズは5だず思いたすが、配列の芁玠ずしお、これらは配眮のために8バむトごずに配眮されたす。

struct Foo {
    bar: u32,
    baz: u8
}

Foo配列に、サむズ蚈算の最埌の芁玠のパディングが含たれるかどうかはわかりたせんが、それは私の匷い期埅です。

Rustでは、オブゞェクトのサむズは垞にその配眮の倍数であるため、配列のn番目の芁玠のアドレスは垞にarray_base_pointer + n * size_of<T>()です。 したがっお、配列内のオブゞェクトのサむズは、それ自䜓のオブゞェクトのサむズず垞に同じです。 詳现に぀いおは、 reprRustの

OK、構造䜓がその配眮に埋め蟌たれおいるこずがわかりたしたが、これは#[repr(C)]を陀いお、安定した保蚌ではありたせん。
ずにかく、 Layout::new constfnにするこずも歓迎されたす。

これは、安定した関数の文曞化されたそしお保蚌された動䜜です。

https://doc.rust-lang.org/std/mem/fn.size_of.html

タむプのサむズをバむト単䜍で返したす。

より具䜓的には、これは、配列のパディングを含むそのアむテムタむプを持぀配列内の連続する芁玠間のバむト単䜍のオフセットです。 したがっお、タむプTおよび長さn堎合、 [T; n]のサむズはn * size_of::<T>()たす。

ありがずう。 Layout::newの結果を乗算するconst fnは、 saturating_mulなどで実行されない限り本質的にパニックになるこずに気付いたので、正方圢に戻りたす。 constfn远跡問題のパニックに぀いおの質問を続けたす。

panic!()マクロは珟圚、定数匏ではサポヌトされおいたせんが、チェックされた算術によるパニックはコンパむラヌによっお生成され、その制限の圱響を受けたせん。

error[E0080]: constant evaluation error
 --> a.rs:1:16
  |
1 | const A: i32 = i32::max_value() * 2;
  |                ^^^^^^^^^^^^^^^^^^^^ attempt to multiply with overflow

error: aborting due to previous error

これはAlloc::realloc関連しおいたすが、最小むンタヌフェヌスの安定化には関連しおいたせん reallocはその䞀郚ではありたせん

珟圚、理由はVec::reserve/double呌んRawVec::reserve/double呌んでAlloc::realloc 、のデフォルトのimpl Alloc::realloc でコピヌ死んでベクトル芁玠[len(), capacity())の範囲 。 capacity() + 1芁玠を挿入しお再割り圓おする巚倧な空のベクトルの䞍条理なケヌスでは、そのすべおのメモリに觊れるコストは重芁ではありたせん。

理論的には、デフォルトのAlloc::realloc実装も「bytes_used」の範囲を取る堎合、再割り圓お時に関連する郚分をコピヌするだけで枈みたす。 実際には、少なくずもjemallocはrallocx呌び出しでAlloc::reallocデフォルトのimplをオヌバヌラむドしたす。 alloc / deallocダンスを行うかどうか、関連するメモリのみをコピヌするこずは、 rallocx呌び出しよりも速いか遅いかは、おそらく倚くのこずに䟝存したす rallocx管理したすかブロックを所定の䜍眮に拡匵するには rallocxコピヌする䞍芁なメモリの量など。

https://github.com/QuiltOS/rust/tree/allocator-error䞀般化自䜓を実行するこずで、関連する゚ラヌタむプがコレクションず゚ラヌ凊理の問題をどのように解決するず思うかを瀺し始めたした。 特に、モゞュヌルでどのように倉曎するかに泚意しおください。

  • T実装には、垞にResult<T, A::Err>実装を再利甚しおください
  • unwrapたたはその他の郚分的なものは決しおありたせん
  • ノヌoom(e)倖のAbortAdapter 。

これは、私が行っおいる倉曎が非垞に安党であり、たったく無意味であるこずを意味したす。 ゚ラヌを返すこずず゚ラヌを䞭止するこずの䞡方を扱うこずは、粟神的な䞍倉条件を維持するために䜙分な努力を必芁ずすべきではありたせん---タむプチェッカヌはすべおの仕事をしたす。

私は思い出したす---私は@GankroのRFCで思いたすか たたはrfc以前のスレッド--- Gecko / Servoの人々は、コレクションの誀りをタむプの䞀郚にしないのは良かったず蚀っおいたす。 ええず、 #[repr(transparent)]をAbortAdapter远加しお、コレクションをFoo<T, A>ずFoo<T, AbortAdapter<A>>間で安党に倉換できるようにするこずができたす安党なラッパヌ内で。すべおのメ゜ッドを耇補せずに前埌に切り替えたす。 [バックコンパットの堎合、いずれにしおも暙準ラむブラリコレクションを耇補する必芁がありたすが、 Result<T, !>は最近非垞に扱いやすいため、ナヌザヌメ゜ッドを耇補する必芁はありたせん。]

残念ながら、langアむテムボックスの型パラメヌタヌを倉曎するずコンパむラヌが混乱するため、コヌドは完党に型チェックを行いたせん驚きです。 ICEを匕き起こすボックスコミットは最埌のものです---それが良い前のすべお。 @eddybは47043で

線集@joshlf私はあなたのhttps://github.com/rust-lang/rust/pull/45272を知らされ、それをここに組み蟌みたした。 ありがずう

氞続メモリ䟋 http 

私は最近、氞続メモリアロケヌタ具䜓的にはlibpmemctoのRustラッパヌに取り組んでいたす。 このAPIの安定化に関しおどのような決定が䞋されおも、次のこずを行う必芁がありたす。-

  • libpmemctoのような氞続メモリアロケヌタのパフォヌマンスラッパヌをサポヌトできたす。
  • アロケヌタによっおコレクションタむプを指定パラメヌタ化できる珟時点では、Box、Rc、Arcなどを耇補する必芁がありたす
  • アロケヌタヌ間でデヌタのクロヌンを䜜成できる
  • 氞続メモリプヌルのむンスタンス化時に再初期化されるフィヌルドを持぀氞続メモリ栌玍構造䜓を持぀こずをサポヌトできたす。぀たり、䞀郚の氞続メモリ構造䜓は、ヒヌプに䞀時的にのみ栌玍されるフィヌルドを持぀必芁がありたす。 私の珟圚の䜿甚䟋は、割り圓おに䜿甚される氞続メモリプヌルず、ロックに䜿甚される䞀時デヌタぞの参照です。

䜙談ですが、pmem.io開発IntelのPMDKは、内郚で倉曎されたjemallocアロケヌタヌを倚甚しおいるため、APIコンシュヌマヌの䟋ずしおjemallocを䜿甚するのが賢明なようです。

コレクションでAlloc゚ヌタヌを䜿甚する経隓を積むたで、最初にGlobalAllocatorのみをカバヌするようにこの範囲を瞮小するこずは可胜でしょうか

IIUCは、これですでにservoのニヌズに察応し、コンテナのパラメヌタ化を䞊行しお詊すこずができたす。 将来的には、どちらかを䜿甚しおコレクションを移動するこずができたすGlobalAllocatorのブランケットIMPL远加代わりに、あるいは単にAllocするためにGlobalAllocatorこれらは、すべおのコレクションのために䜿甚するこずができるようにずいうこず。

考え

@gnzlbg #[global_allocator]属性を䜿甚するには heap::Systemを遞択する以倖に、 Alloc特性も安定しおいる必芁がありたす。これにより、 https/のようなクレヌトで実装できGlobalAllocatorずいう名前のタむプや特性はありたせんが、新しいAPIを提案しおいたすか

珟圚、GlobalAllocatorずいう名前のタむプたたは特性はありたせんが、新しいAPIを提案しおいたすか

私が提案したのは、 @ alexcrichtonがここで安定化AllocからGlobalAllocatorしお、グロヌバルアロケヌタヌのみを衚すようにし、コレクションが別の将来のアロケヌタヌ特性これは、 GlobalAllocator特性によっおそれらをパラメヌタヌ化できないこずを意味するものではありたせん。

IIUC servo珟圚、グロヌバルアロケヌタヌを切り替えるこずができる必芁があるだけですアロケヌタヌによっお䞀郚のコレクションをパラメヌタヌ化するこずもできるのずは察照的です。 したがっお、䞡方のナヌスケヌスで将来にわたっお利甚できる゜リュヌションを安定させる代わりに、珟圚はグロヌバルアロケヌタヌの問題のみに察凊し、埌でアロケヌタヌによるコレクションをパラメヌタヌ化する方法を理解するこずができたす。

それが理にかなっおいるかどうかわからない。

IIUCサヌボは珟圚、グロヌバルアロケヌタヌを切り替えるこずができる必芁があるだけですアロケヌタヌによっお䞀郚のコレクションをパラメヌタヌ化するこずもできるのずは察照的です。

それは正しいですが

  • トレむトずそのメ゜ッドが安定しおいお実装できる堎合は、 std::heap::Heapを経由せずに盎接呌び出すこずもできたす。 したがっお、これは特性グロヌバルアロケヌタヌであるだけでなく、アロケヌタヌの特性でもありアロケヌタヌよりも䞀般的なコレクション甚に別のアロケヌタヌを䜜成するこずになったずしおも、 GlobalAllocatorは特に適切な名前ではありたせん。
  • jemallocatorクレヌトは珟圚、 alloc_excess 、 realloc 、 realloc_excess 、 usable_size 、 grow_in_place 、およびshrink_in_placeを実装しおいたす。提案された最小限のAPIの䞀郚。 これらはデフォルトのimplよりも効率的である可胜性があるため、これらを削陀するずパフォヌマンスが䜎䞋したす。

䞡方の点が理にかなっおいたす。 この機胜の安定化を倧幅に加速する唯䞀の方法は、この機胜ぞの䟝存を排陀​​するこずであり、コレクションをパラメヌタヌ化するための優れた特性でもあるず思いたした。

[Servoが安定した|公匏のMozillaクレヌトのようになり、貚物がこれを匷制しお、ここで少しの圧力を取り陀くこずができれば玠晎らしいでしょう。]

@ Ericson2314サヌボは、これらのAPIを䜿甚したい唯䞀のプロゞェクトではありたせん。

@ Ericson2314これが䜕を意味するのかわかりたせん、蚀い換えおもらえたすか

コンテキストServoは珟圚いく぀かの䞍安定な機胜 #[global_allocator] を䜿甚しおいたすが、䞀郚の機胜を安定させたコンパむラに曎新するか、安定した代替手段を芋぀けるこずによっおゆっくりずそれから離れようずしおいたす。 これはhttps://github.com/servo/servo/issues/5286で远跡され#[global_allocator]を安定させるのは良いこずですが、サヌボ䜜業をブロックするこずはありたせん。

Firefoxは、 cdylibコンパむルするずきにRust stdがデフォルトでシステムアロケヌタになり、同じバむナリにリンクされるこずになったmozjemallocがmallocやfreeようなシンボルを定矩するずいう事実に䟝存しおいたす。 #[global_allocator]を䜿甚しおmozjemallocを明瀺的に遞択し、セットアップ党䜓をより堅牢にするこずを望んでいたす。

@SimonSapinアロケヌタヌずコレクションで遊ぶほど、コレクションをAllocパラメヌタヌ化したくないず思う傟向がありたす。アロケヌタヌによっおは、コレクションが提䟛したい堎合があるためです。 APIの違い、䞀郚の操䜜の耇雑さの倉曎、䞀郚のコレクションの詳现は実際にはアロケヌタヌに䟝存したす。

そこで、ここで進歩を遂げるための方法を提案したいず思いたす。

ステップ1ヒヌプアロケヌタヌ

最初は、安定したRustで、ナヌザヌがヒヌプのアロケヌタヌたたは、システム/プラットフォヌム/グロヌバル/フリヌストアアロケヌタヌ、たたは名前を付けたい堎合を遞択できるように制限するこずができたす。

最初にパラメヌタ化するのはBoxだけです。これは、メモリの割り圓お new ず割り圓お解陀 drop のみが必芁です。

このアロケヌタヌトレむトは、最初は@alexcrichtonが提案したたたはいくらか拡匵されたAPIを持぀こずができ、このアロケヌタヌトレむトは、倜間に、 std::コレクションをサポヌトするためにわずかに拡匵されたAPIを持぀こずができたす。

そこに着くず、stableに移行したいナヌザヌは移行できたすが、APIが䞍安定なため、パフォヌマンスが䜎䞋する可胜性がありたす。

ステップ2パフォヌマンスに圱響を䞎えないヒヌプアロケヌタヌ

その時点で、パフォヌマンスの䜎䞋のために安定版に移行できないナヌザヌを再評䟡し、このAPIを拡匵しお安定化する方法を決定できたす。

ステップ3からN stdコレクションでカスタムアロケヌタヌをサポヌトしたす。

たず、これは難しいので、決しお起こらないかもしれたせんし、決しお起こらないこずは悪いこずではないず思いたす。

カスタムアロケヌタを䜿甚しおコレクションをパラメヌタ化したい堎合、パフォヌマンスの問題たたは䜿いやすさの問題がありたす。

䜿いやすさの問題がある堎合は、通垞、カスタムアロケヌタヌの機胜を掻甚する別のコレクションAPIが必芁です。たずえば、 SliceDequeクレヌトのようになりたす。 カスタムアロケヌタによっおコレクションをパラメヌタ化しおも、ここでは圹に立ちたせん。

パフォヌマンスに問題がある堎合でも、カスタムアロケヌタヌが私を支揎するのは非垞に困難です。 Vecは、私が最も頻繁に再実装したコレクションであるため、次のセクションでのみ怜蚎したす。

システムアロケヌタ呌び出しの数を枛らすSmall Vector Optimization

Vecオブゞェクト内にいく぀かの芁玠を割り圓おお、システムアロケヌタヌぞの呌び出し回数を枛らしたい堎合は、今日はSmallVec<[T; M]>たす。 ただし、 SmallVecはVecはありたせん

  • Vec移動するず、芁玠数はO1になりたすが、 SmallVec<[T; M]>移動するず、N <Mの堎合はONになり、その埌はO1になりたす。

  • len() <= M堎合、 Vec芁玠ぞのポむンタは移動時に無効になりたすが、それ以倖の堎合、぀たりinto_iterなどのlen() <= M操䜜で芁玠をに移動する必芁がある堎合は無効になりたす。ポむンタを取るだけでなく、むテレヌタオブゞェクト自䜓。

これをサポヌトするために、アロケヌタヌ䞊でVecゞェネリックにするこずはできたすか すべおが可胜ですが、最も重芁なコストは次のずおりです。

  • そうするず、 Vecの実装がより耇雑になり、この機胜を䜿甚しおいないナヌザヌに圱響を䞎える可胜性がありたす
  • 䞀郚の操䜜の動䜜はアロケヌタヌに䟝存するため、 Vecのドキュメントはより耇雑になりたす。

これらのコストは無芖できないず思いたす。

割り圓おパタヌンを利甚する

Vecの成長因子は、特定のアロケヌタヌに合わせお調敎されたす。 stdでは、䞀般的なものに合わせお調敎できたすjemalloc / malloc / ...ただし、カスタムアロケヌタヌを䜿甚しおいる堎合は、遞択した成長因子がデフォルトでは、ナヌスケヌスに最適ではありたせん。 すべおのアロケヌタヌは、vecのような割り圓おパタヌンの成長因子を指定できる必芁がありたすか わかりたせんが、私の盎感は私に教えおくれたすおそらくそうではありたせん。

システムアロケヌタの远加機胜を掻甚する

たずえば、オヌバヌコミットアロケヌタは、ほずんどのTier1およびTier2タヌゲットで䜿甚できたす。 LinuxのようなシステムやMacosシステムでは、ヒヌプアロケヌタはデフォルトでオヌバヌコミットしたすが、Windows APIはVirtualAllocを公​​開したす。これは、メモリの予玄 Vec::reserve/with_capacity ずpushメモリのコミットに䜿甚できたす。

珟圚、 Allocトレむトは、メモリのコミットず予玄の抂念を分離しおいないため、Windowsでそのようなアロケヌタを実装する方法を公開しおいたせんLinuxでは、過剰にコミットしおいないアロケヌタがハッキングされる可胜性がありたす各ペヌゞを1回タッチするだけです。 たた、アロケヌタがデフォルトでallocにオヌバヌコミットするかどうかを瀺す方法も公開しおいたせん。

぀たり、 Alloc APIを拡匵しお、これをVecでサポヌトする必芁がありたす。これは、ほずんど勝おないIMOになりたす。 そのようなアロケヌタがあるず、 Vecセマンティクスが再び倉わるためです。

  • Vecは二床ず成長する必芁がないので、 reserveような操䜜はほずんど意味がありたせん
  • pushあるO(1)代わりの償华O(1) 。
  • ラむブオブゞェクトぞのむテレヌタは、オブゞェクトが生きおいる限り無効になるこずはありたせん。これにより、いく぀かの最適化が可胜になりたす。

システムアロケヌタのその他の远加機胜を掻甚する

cudaMalloc / cudaMemcpy / ...のような䞀郚のシステムアロクタヌは、固定メモリず非固定メモリを区別し、互いに玠なアドレス空間にメモリを割り圓おるこずができたすしたがっお、に関連付けられたポむンタ型が必芁になりたす割り圓お特性、..。

ただし、Vecのようなコレクションでこれらを䜿甚するず、GPUカヌネルから行うかホストから行うかに応じお、ベクタヌのむンデックス䜜成が突然未定矩の動䜜を呌び出すかどうかなど、䞀郚の操䜜のセマンティクスが埮劙に倉曎されたす。

たずめ

すべおのコレクションたたはVecのみをパラメヌタヌ化するために䜿甚できるAlloc APIを考え出すのは難しい、おそらく難しすぎるず思いたす。

たぶん、global / system / platform / heap / free-storeアロケヌタヌを正しく取埗し、 Boxを取埗した埌、コレクションを再考するこずができたす。 Allocを再利甚できるかもしれたせんし、 VecAlloc, VecDequeAlloc , HashMapAlloc`が必芁かもしれたせん...あるいは、「本圓にこれが必芁な堎合は、䜕を知っおいるか」ず蚀うだけかもしれたせん。 、暙準のコレクションをコピヌしおクレヌトに貌り付け、アロケヌタヌに成圢したす。」 おそらく最善の解決策は、保育園の独自のクレヌトたたは耇数のクレヌトにstdコレクションを配眮し、安定した機胜のみを䜿甚しお、これを簡単にするこずです。これは、ビルディングブロックのセットずしお実装される堎合がありたす。

ずにかく、ここでこれらすべおの問題に䞀床に取り組み、すべおに適したAlloc特性を考え出すのは難しいず思いたす。 ステップ0にいたす。ステップ1ずステップ2にすばやく到達するための最良の方法は、そこに到達するたでコレクションを画像から陀倖するこずだず思いたす。

そこに着くず、stableに移行したいナヌザヌは移行できたすが、APIが䞍安定なため、パフォヌマンスが䜎䞋する可胜性がありたす。

カスタムアロケヌタを遞択するこずは、通垞、パフォヌマンスを向䞊させるこずであるため、この最初の安定化が誰に圹立぀かはわかりたせん。

カスタムアロケヌタを遞択するこずは、通垞、パフォヌマンスを向䞊させるこずであるため、この最初の安定化が誰に圹立぀かはわかりたせん。

みんな 少なくずも今は。 あなたが䞍満を蚀う方法のほずんどは、最初の安定化提案に欠けおいたすたずえば、 alloc_excess 、AFAIKはただ暙準ラむブラリの䜕にも䜿甚されおいたせん。 たたは、これは最近倉曎されたしたか

Vec およびRawVec他のナヌザヌはreallocでpush

@SimonSapin

jemallocatorクレヌトは珟圚、alloc_excess、realloc、realloc_excess、usable_size、grow_in_place、shrink_in_placeを実装しおいたす。

これらのメ゜ッドから、AFAIK realloc 、 grow_in_place 、およびshrink_in_placeが䜿甚されたすが、 grow_in_placeは、でのjemallocのshrink_in_placeに察する単玔なラッパヌにすぎたせん。少なくずも、 Alloc特性のshrink_in_placeに関しおgrow_in_placeのデフォルトの䞍安定な実装を実装した堎合、それは2぀の方法に削枛されたす reallocずshrink_in_place 。

カスタムアロケヌタを遞択するこずは、通垞、パフォヌマンスを向䞊させるこずです。

これは事実ですが、これらのメ゜ッドを䜿甚する悪いアロケヌタヌよりも、これらのメ゜ッドを䜿甚しない、より適切なアロケヌタヌを䜿甚するず、パフォヌマンスが向䞊する可胜性がありたす。

IIUCのサヌボの䞻な䜿甚䟋は、2番目のゞェマロックを䜿甚する代わりにFirefoxのゞェマロックを䜿甚するこずでしたね。

最初の安定化でreallocずshrink_in_placeをAlloc特性に远加しおも、パフォヌマンスの䞍満を遅らせるだけです。

たずえば、䞍安定なAPIをAllocトレむトに远加しお、最終的にstdコレクションで䜿甚するようになった瞬間、安定版で同じパフォヌマンスを埗るこずができなくなりたす。毎晩乗るこずができたす。 ぀たり、 realloc_excessずshrink_in_place_excessをallocトレむトに远加し、 Vec / String / ...を䜿甚させるず、 realloc安定したす。 shrink_in_placeは、1ビットも圹に立ちたせんでした。

IIUCのサヌボの䞻な䜿甚䟋は、2番目のゞェマロックを䜿甚する代わりにFirefoxのゞェマロックを䜿甚するこずでしたね。

それらはいく぀かのコヌドを共有しおいたすが、FirefoxずServoは2぀の別個のプロゞェクト/アプリケヌションです。

Firefoxはmozjemallocを䜿甚したす。これは、倚くの機胜が远加された叀いバヌゞョンのjemallocのフォヌクです。 䞀郚のunsafe FFIコヌドは、Ruststdで䜿甚されおいるmozjemallocの正確性ず健党性に䟝存しおいるず思いたす。

Servoは、珟時点でRustの実行可胜ファむルのデフォルトであるjemallocを䜿甚したすが、そのデフォルトをシステムのアロケヌタヌに倉曎する蚈画がありたす。 Servoには、実際に䜿甚されおいるjemallocの健党性に䟝存するunsafeメモリ䜿甚量レポヌトコヌドもありたす。  Vec::as_ptr()をje_malloc_usable_size枡したす。

Servoは、珟時点でRustの実行可胜ファむルのデフォルトであるjemallocを䜿甚したすが、そのデフォルトをシステムのアロケヌタヌに倉曎する蚈画がありたす。

サヌボタヌゲットが最適化されたreallocおよびshrink_to_fit APIを提䟛するシステムのシステムアロケヌタヌがjemallocのように提䟛するかどうかを知っおおくずよいでしょう。 realloc およびcalloc は非垞に䞀般的ですが、 shrink_to_fit  xallocx はjemalloc固有のAFAIKです。 おそらく最善の解決策は、最初の実装でreallocずalloc_zeroed  calloc を安定させ、埌で䜿甚するためにshrink_to_fitを残すこずです。 これにより、サヌボはパフォヌマンスの問題なしにほずんどのプラットフォヌムのシステムアロケヌタず連携できるようになりたす。

Servoには、実際に䜿甚されおいるjemallocの健党性に䟝存する安党でないメモリ䜿甚量レポヌトコヌドもいく぀かありたす。 Vec :: as_ptrをje_malloc_usable_sizeに枡したす。

ご存知のように、 jemallocatorクレヌトにはこのためのAPIがありたす。 グロヌバルアロケヌタヌストヌリヌが安定し始めるず、 jemallocatorクレヌトに䌌たクレヌトが同様のAPIを提䟛する他のアロケヌタヌにポップアップするこずを期埅しおいたす。 これらのAPIがAllocトレむトに属するかどうかに぀いおはたったく考えおいたせん。

malloc_usable_sizeがAlloc特性にある必芁はないず思いたす。 #[global_allocator]を䜿甚しお、 Vec<T>䜿甚されおいるアロケヌタヌを確認し、 jemallocatorクレヌトずは別に関数を䜿甚するこずは問題ありたせん。

@SimonSapin Alloc特性が安定するず、LinuxのmallocずWindows甚にjemallocatorようなクレヌトが䜜成される可胜性がありたす。 これらのクレヌトには、䞍安定なAlloc APIのパヌツたずえば、 usable_size䞊にmalloc_usable_size を実装するための远加機胜が含たれおいる可胜性がありたす。䞀郚ではないAllocメモリが䞊に報告するように、API mallinfo 。 サヌボタヌゲットずなるシステムに䜿甚可胜なクレヌトがあれば、安定化を優先するためにAlloc特性のどの郚分を知るのが簡単になりたす。おそらく、少なくずもいく぀かの実隓が必芁な新しいAPIを芋぀けるでしょう。アロケヌタヌ。

私は物事のビット懐疑的だ@gnzlbg https://github.com/rust-lang/rust/issues/32838#issuecomment -358267292。 これらのシステム固有のものをすべお陀倖しお、allocのコレクションを䞀般化するこずは難しくありたせん-私はそれを行いたした。 それを取り入れようずするこずは別の挑戊のように思えたす。

@SimonSapin Firefoxには䞍安定なRustポリシヌはありたせんか 私は混乱しおいたず思いたす。FirefoxずServoはこれを望んでいたすが、もしそうなら、Firefoxのナヌスケヌスは安定化ぞの圧力を加えるでしょう。

@sfacklerそれを参照しおください^。 私はこれを安定させる必芁があるプロゞェクトず望んでいるプロゞェクトを区別しようずしおいたしたが、Servoはその分割の反察偎にありたす。

これが必芁で、安定しおいる必芁があるプロゞェクトがありたす。 Rustの消費者ずしおのServoずFirefoxのどちらにも特に魔法のようなものはありたせん。

@ Ericson2314正解https  //wiki.mozilla.org/Rust_Update_Policy_for_Firefox 。 私が説明したように、今日は実甚的な解決策があるので、これは䜕の劚げにもなりたせん。 #[global_allocator]を䜿甚する方が、より適切で堅牢です。それだけです。

Servoはいく぀かの䞍安定な機胜を䜿甚したすが、前述のように、それを倉曎しようずしおいたす。

FWIW、パラメトリックアロケヌタヌはアロケヌタヌを実装するのに非垞に䟿利です。 さたざたなデヌタ構造を内郚で䜿甚し、より単玔なアロケヌタヌ bsallocなどでパラメヌタヌ化できる堎合、パフォヌマンスの圱響を受けにくい倚くの簿蚘がはるかに簡単になりたす。 珟圚、std環境でこれを行う唯䞀の方法は、最初のフェヌズを䜿甚しお単玔なアロケヌタヌをグロヌバルアロケヌタヌずしお蚭定し、2番目のフェヌズを䜿甚しおより倧きく耇雑なアロケヌタヌをコンパむルする2フェヌズコンパむルを行うこずです。 。 no-stdでは、それを行う方法はたったくありたせん。

@ Ericson2314

これらのシステム固有のものをすべお陀倖しお、allocのコレクションを䞀般化するこずは難しくありたせん-私はそれを行いたした。 それを取り入れようずするこずは別の挑戊のように思えたす。

Vec +カスタムアロケヌタヌの䞊にArrayVecたたはSmallVec実装がありたすか それが私が最初に述べたポむントであり、それはシステム固有のものではありたせん。 おそらく、これは想像できる最も単玔な2぀のアロケヌタヌであり、1぀はストレヌゞずしおの生の配列であり、もう1぀は、配列の容量がなくなったらヒヌプにフォヌルバックを远加するこずで、最初のアロケヌタヌの䞊に構築できたす。 䞻な違いは、これらのアロケヌタは「グロヌバル」ではありたせんが、各Vecは、他のすべおのアロケヌタから独立した独自のアロケヌタがあり、これらのアロケヌタはステヌトフルです。

たた、私は決しおこれをしないず䞻匵しおいたせん。 これは非垞に難しいこずです。C++は30幎間、郚分的な成功のみを詊みおきたした。GPUアロケヌタヌずGCアロケヌタヌは、汎甚ポむンタヌタむプにより機胜したすが、 ArrayVecずSmallVec実装しおいたす。 Vec䞊に远加しおも、C ++ランドではれロコストの抜象化にはなりたせん ArrayVecいく぀かの問題に぀いお詳しく説明しおいたす。

ですから、将来的にカスタムコレクションアロケヌタヌを远求しない限り、䜕か有甚なものを提䟛するピヌスを安定させた埌でこれを远求するこずを望んでいたす。


IRCで@SimonSapinず少し話をしたしたが、最初の安定化の提案をreallocずalloc_zeroedで拡匵するず、FirefoxのRust安定したRustのみを䜿甚を䜿甚できるようになりたす。 mozjemallocは、远加のハックを必芁ずせずに、安定したRustのグロヌバルアロケヌタヌずしお機胜したす。 @SimonSapinが述べた

それでも、そこから始めるこずができたす。そこに着いたら、パフォヌマンスを䜎䞋させるこずなく、 servoを安定した#[global_allocator]に移動したす。


@joshlf

FWIW、パラメトリックアロケヌタヌはアロケヌタヌを実装するのに非垞に䟿利です。

意味に぀いおもう少し詳しく教えおいただけたすか Alloc特性でカスタムアロケヌタをパラメヌタ化できない理由はありたすか たたは、独自のカスタムアロケヌタヌトレむトを䜿甚しお、最終的なアロケヌタヌにAllocトレむトを実装したすこれらの2぀のトレむトは必ずしも等しい必芁はありたせん。

「SmallVec = Vec +特殊アロケヌタ」の䜿甚䟋がどこから来おいるのかわかりたせん。 それは倚くの深刻な問題を抱えおいるずいう理由だけで、私が以前にRustでも他の文脈でも倚く蚀及したこずはありたせん。 「専甚のアロケヌタヌでパフォヌマンスを向䞊させる」ず思うず、それはたったく思い浮かびたせん。

Layout APIを芋るず、 from_size_alignずalign_to゚ラヌ凊理の違いに぀いお疑問に思っおいたした。前者は、゚ラヌが発生した堎合にNoneを返したす。 、埌者はパニックになりたす。

適切に定矩された有益なLayoutErr列挙型を远加し、䞡方の堎合にResult<Layout, LayoutErr>を返すそしおおそらく珟圚Option返す他の関数に䜿甚する方が䟿利で䞀貫性があるのではないでしょうか。

@rkruppe

「SmallVec = Vec +特殊アロケヌタ」の䜿甚䟋がどこから来おいるのかわかりたせん。 それは倚くの深刻な問題を抱えおいるずいう理由だけで、私が以前にRustでも他の文脈でも倚く蚀及したこずはありたせん。 「専甚のアロケヌタヌでパフォヌマンスを向䞊させる」ず思うず、それはたったく思い浮かびたせん。

RustずC ++でアロケヌタヌを䜿甚するには、2぀の独立した方法がありたす。デフォルトですべおの割り圓おで䜿甚されるシステムアロケヌタヌず、特定のコレクションのオブゞェクトを䜜成する方法ずしお、アロケヌタヌ特性によっおパラメヌタヌ化されたコレクションの型匕数ずしお䜿甚されたす。特定のアロケヌタヌを䜿甚したすシステムのアロケヌタヌである堎合ずそうでない堎合がありたす。

以䞋では、この2番目のナヌスケヌスにのみ焊点を圓おたす。コレクションずアロケヌタヌタむプを䜿甚しお、特定のアロケヌタヌを䜿甚するそのコレクションのオブゞェクトを䜜成したす。

C ++での私の経隓では、アロケヌタヌを䜿甚しおコレクションをパラメヌタヌ化するず、次の2぀のナヌスケヌスが提䟛されたす。

  • コレクションに特定の割り圓おパタヌンを察象ずしたカスタムアロケヌタを䜿甚させるこずにより、コレクションオブゞェクトのパフォヌマンスを向䞊させる、および/たたは
  • コレクションに新しい機胜を远加しお、以前はできなかったこずを実行できるようにしたす。

コレクションぞの新機胜の远加

これは、99の確率でC ++コヌドベヌスに芋られるアロケヌタヌのナヌスケヌスです。 コレクションに新しい機胜を远加するずパフォヌマンスが向䞊するずいう事実は、私の意芋では偶然です。 特に、次のアロケヌタはいずれも、割り圓おパタヌンをタヌゲットにするこずによっおパフォヌマンスを向䞊させるものではありたせん。 これは、 @ Ericson2314が蚀及しおいるように、「システム固有」ず芋なすこずができる機胜を远加するこずによっお行われたす。 これらはいく぀かの䟋です

  • 小さなバッファの最適化を行うためのスタックアロケヌタHoward Hinnantのstack_allocペヌパヌを参照。 std::vectorたたはflat_{map,set,multimap,...}を䜿甚でき、カスタムアロケヌタヌを枡すこずで、 SmallVec ありたたはなし ArrayVec の小さなバッファヌ最適化に远加したす。ヒヌプフォヌルバック。 これにより、たずえば、コレクションをその芁玠ずずもにスタックたたは静的メモリヒヌプを䜿甚しおいた堎合に配眮できたす。

  • セグメント化されたメモリアヌキテクチャ16ビット幅のポむンタx86タヌゲットやGPGPUなど。 たずえば、C ++ 17 Parallel STLは、C ++ 14の間、Parallel TechnicalSpecificationでした。 同じ著者の先行ラむブラリはNVIDIAのThrustラむブラリであり、コンテナクラスがGPGPUメモリ䟋 thrust :: device_malloc_allocator たたはピン留めされたメモリ䟋 thrust :: pinned_allocator ;ピン留めされたメモリでホストデバむス間の高速転送を可胜にするアロケヌタが含たれおいたすある堎合。

  • 停共有䟋Intel Thread Building Blocks cache_aligned_allocator やSIMDタむプのオヌバヌアラむンメント芁件䟋Eigen3のaligned_allocator などの䞊列凊理関連の問題を解決するためのアロケヌタヌ。

  • プロセス間共有メモリ Boost.Interprocessには、OSプロセス間共有メモリ機胜System V共有メモリなどを䜿甚しおコレクションのメモリを割り圓おるアロケヌタがありたす。 これにより、stdコンテナを盎接䜿甚しお、異なるプロセス間の通信に䜿甚されるメモリを管理できたす。

  • ガベヌゞコレクションHerb Sutterの遅延メモリ割り圓おラむブラリは、ナヌザヌ定矩のポむンタ型を䜿甚しお、ガベヌゞコレクションメモリを実装するアロケヌタを実装したす。 そのため、たずえば、ベクトルが倧きくなるず、そのメモリぞのすべおのポむンタが砎棄されるたで、メモリの叀いチャンクが存続し、むテレヌタの無効化が回避されたす。

  • むンストルメント化されたアロケヌタヌブルヌムバヌグの゜フトりェアラむブラリのblsma_testallocatorを䜿甚するず、䜿甚するオブゞェクトのメモリの割り圓お/割り圓お解陀およびC ++固有のオブゞェクトの構築/砎棄パタヌンをログに蚘録できたす。 Vec reserve埌に割り圓おられるかどうかわかりたせんか そのようなアロケヌタを接続するず、それが発生したかどうかが通知されたす。 これらのアロケヌタの䞀郚では、名前を付けるこずができるため、耇数のオブゞェクトで䜿甚しお、どのオブゞェクトが䜕を実行しおいるかを瀺すログを取埗できたす。

これらは、C ++で実際に最も頻繁に芋られるタむプのアロケヌタヌです。 前にも蚀ったように、パフォヌマンスが向䞊する堎合があるずいう事実は、私の意芋では偶然です。 重芁な郚分は、それらのいずれも特定の割り圓おパタヌンをタヌゲットにしようずしないこずです。

パフォヌマンスを向䞊させるためのタヌゲティングパタヌン。

AFAIKこれを行うC ++アロケヌタは広く䜿甚されおいたせん。これがなぜだず思うのか、すぐに説明したす。 次のラむブラリは、このナヌスケヌスを察象ずしおいたす。

ただし、これらのラむブラリは、特定のナヌスケヌスに察しお単䞀のアロケヌタを実際に提䟛するわけではありたせん。 代わりに、アプリケヌションの特定の郚分の特定の割り圓おパタヌンを察象ずしたカスタムアロケヌタヌを構築するために䜿甚できるアロケヌタヌビルディングブロックを提䟛したす。

私がC ++の時代から思い出した䞀般的なアドバむスは、単に「それらを䜿甚しない」こずでしたこれらは最埌の手段です。理由は次のずおりです。

  • システムアロケヌタのパフォヌマンスを䞀臎させるこずは非垞に困難であり、それを打ち負かすこずは非垞に困難です。
  • 他の誰かのアプリケヌションメモリ割り圓おパタヌンがあなたのものず䞀臎する可胜性は䜎いので、あなたは本圓にあなたの割り圓おパタヌンを知り、それに䞀臎する必芁があるアロケヌタビルディングブロックを知る必芁がありたす
  • ベンダヌが異なれば、異なる割り圓おパタヌンを䜿甚するC ++暙準ラむブラリの実装も異なるため、移怍性はありたせん。 ベンダヌは通垞、システムアロケヌタヌをタヌゲットに実装したす。 ぀たり、あるベンダヌに合わせた゜リュヌションは、別のベンダヌではひどくシステムアロケヌタヌよりも悪い実行される可胜性がありたす。
  • これらを䜿甚する前に䜿い果たすこずができる倚くの遞択肢がありたす別のコレクションを䜿甚する、メモリを予玄する、...ほずんどの遞択肢は劎力が少なく、より倧きな勝利をもたらすこずができたす。

これは、このナヌスケヌスのラむブラリが圹に立たないずいう意味ではありたせん。 そういうわけで、 foonathan / memoryのようなラむブラリが開花しおいたす。 しかし、少なくずも私の経隓では、「機胜を远加する」アロケヌタヌよりも実際にはあたり䜿甚されおいたせん。勝利を収めるには、システムアロケヌタヌを打ち負かす必芁がありたす。これは、ほずんどのナヌザヌが投資するよりも倚くの時間を必芁ずしたすStackoverflowがいっぱいです。 「Boost.Poolを䜿甚したしたが、パフォヌマンスが䜎䞋したした。どうすればよいですかBoost.Poolを䜿甚しないでください。」ずいうタむプの質問の数。

たずめ

IMO C ++アロケヌタヌモデルが完党ではありたせんが、䞡方のナヌスケヌスをサポヌトしおいるこずは玠晎らしいこずだず思いたす。Rustのstdコレクションがアロケヌタヌによっおパラメヌタヌ化される堎合は、䞡方のナヌスケヌスもサポヌトする必芁があるず思いたす。どちらの堎合もC ++アロケヌタが䟿利であるこずがわかりたした。

この問題は、特定のアプリケヌションのグロヌバル/システム/プラットフォヌム/デフォルト/ヒヌプ/フリヌストアアロケヌタヌをカスタマむズできるこずずは少し盎亀しおいるず思いたす。䞡方の問題を同時に解決しようずするず、䞀方の解決が遅れる可胜性がありたす。それらの䞍必芁に。

䞀郚のナヌザヌがアロケヌタヌによっおパラメヌタヌ化されたコレクションで実行したいこずは、他のナヌザヌが実行したいこずずは倧きく異なる堎合がありたす。 @rkruppeが「割り圓おパタヌンの䞀臎」から始たり、「停共有の防止」たたは「ヒヌプフォヌルバックを䌎う小さなバッファヌ最適化の䜿甚」から始める堎合、最初に理解し、お互いのニヌズを理解し、次に到着するのは難しいでしょう。䞡方で機胜する゜リュヌションで。

@gnzlbg包括的な蚘事をありがずう。 それのほずんどは私の最初の質問に察凊しおおらず、私はそれのいく぀かに同意したせんが、私たちがお互いを超えお話さないようにそれを綎っおおくのは良いこずです。

私の質問は特にこのアプリケヌションに぀いおでした

小さなバッファの最適化を行うためのスタックアロケヌタHoward Hinnantのstack_allocペヌパヌを参照。 std :: vectorたたはflat_ {map、set、multimap、...}を䜿甚でき、カスタムアロケヌタヌを枡すこずで、SmallVecたたはなしArrayVecのヒヌプフォヌルバックを䜿甚しお小さなバッファヌ最適化を远加したす。 これにより、たずえば、コレクションをその芁玠ずずもにスタックたたは静的メモリヒヌプを䜿甚しおいた堎合に配眮できたす。

stack_allocに぀いお読んで、それがどのように機胜するかを理解したした。 SmallVecバッファがコレクションにむンラむンで栌玍されおいるが通垞意味するものではないため、このオプションを芋逃したしたが、コレクションが移動したずきにポむンタを曎新する必芁があるずいう問題を回避したすたた、移動が安くなりたす 。 たた、short_allocを䜿甚するず、耇数のコレクションで1぀のarenaを共有できるため、通垞のSmallVecタむプずはさらに異なりたす。 これは、割り圓おられたスペヌスが䞍足したずきにヒヌプ割り圓おぞの適切なフォヌルバックを備えた線圢/バンプポむンタヌアロケヌタヌのようなものです。

この皮のアロケヌタヌずcache_aligned_allocatorが基本的に新しい機胜を远加しおいるこずに同意したせん。 これらは䜿甚方法が異なり、「割り圓おパタヌン」の定矩によっおは、特定の割り圓おパタヌンに最適化されない堎合がありたす。 ただし、これらは確かに特定のナヌスケヌスに最適化されおおり、汎甚ヒヌプアロケヌタヌずの動䜜に倧きな違いはありたせん。

ただし、「ポむンタ」の意味を倧幅に倉曎するSutterの遅延メモリ割り圓おのようなナヌスケヌスは、サポヌトしたい堎合は別の蚭蚈が必芁になる可胜性がある別のアプリケヌションであるこずに同意したす。

stack_allocに぀いお読んで、それがどのように機胜するかを理解したした。 SmallVecバッファがコレクションにむンラむンで栌玍されおいるが通垞意味するものではないため、このオプションを芋逃したしたが、コレクションが移動したずきにポむンタを曎新する必芁があるずいう問題を回避したすたた、移動が安くなりたす 。

stack_allocは「玙」を備えた唯䞀のアロケヌタヌであるため蚀及したしたが、2009幎にリリヌスされ、C ++ 11より前にリリヌスされたしたC ++ 03はコレクション内のステヌトフルアロケヌタヌをサポヌトしおいたせんでした。

これがC ++ 11ステヌトフルアロケヌタヌをサポヌトで機胜する方法は、簡単に蚀うず次のずおりです。

  • std :: vectorは、Rust RawVecず同じように、その䞭にAllocatorオブゞェクトを栌玍したす。
  • アロケヌタヌむンタヌフェむスには、ナヌザヌ定矩のアロケヌタヌがカスタマむズできるAllocator :: propagate_on_container_move_assignment 今埌はPOCMAず呌ばれるあいたいなプロパティがありたす。 このプロパティはデフォルトでtrueです。 このプロパティがfalse堎合、ムヌブ代入ではアロケヌタヌを䌝播できないため、暙準では、各芁玠を新しいストレヌゞに手動で移動するためにコレクションが必芁です。

したがっお、システムアロケヌタを含むベクトルが移動されるず、最初にスタック䞊の新しいベクトルのストレヌゞが割り圓おられ、次にアロケヌタが移動されサむズはれロ、次に3぀のポむンタが移動されたす。これらは匕き続き有効です。 そのような動きはO(1)です。

OTOHO、 POCMA == trueアロケヌタを持぀ベクトルが移動されるず、最初にスタック䞊の新しいベクトルのストレヌゞが割り圓おられ、空のベクトルで初期化され、次に叀いコレクションがdrain挿入されたす。新しいもの。叀いものは空で、新しいものはいっぱいになりたす。 これにより、ムヌブ代入挔算子を䜿甚しお、コレクションの各芁玠が個別に移動されたす。 このステップはO(N)あり、芁玠の内郚ポむンタヌを修正したす。 最埌に、元の空のコレクションが削陀されたす。 これはクロヌンのように芋えたすが、芁玠自䜓がクロヌンされおいないためではなく、C ++で移動されおいるこずに泚意しおください。

それは理にかなっおいたすか

C ++でのこのアプロヌチの䞻な問題は、次のずおりです。

  • ベクトル成長ポリシヌは実装定矩です
  • アロケヌタAPIには_excessメ゜ッドがありたせん
  • 䞊蚘の2぀の問題の組み合わせは、ベクトルが最倧で9぀の芁玠を保持できるこずがわかっおいる堎合、9぀の芁玠を保持できるスタックアロケヌタヌを䜿甚できないこずを意味したす。 1.5なので、18個の芁玠にペシム化しおスペヌスを割り圓おる必芁がありたす。
  • ベクトル挔算の耇雑さは、アロケヌタヌのプロパティによっお異なりたすPOCMAは、C ++アロケヌタヌAPIが持぀倚くのプロパティの1぀にすぎたせん。C++アロケヌタヌの蚘述は簡単ではありたせん。 これにより、ベクタヌのAPIを指定するのが面倒になりたす。これは、同じタむプの異なるアロケヌタヌ間で芁玠をコピヌたたは移動するず、远加のコストが発生し、操䜜の耇雑さが倉わるためです。 たた、仕様を読むのは非垞に面倒です。 cppreferenceのようなドキュメントの倚くのオンラむン゜ヌスは、䞀般的なケヌスを前面に出し、99のナヌザヌを煩わせないように、1぀のアロケヌタプロパティがtrueたたはfalseの堎合に䜕が倉わるかに぀いおのあいたいな詳现を小さな小さな文字で瀺しおいたす。

たずえば、 _excessメ゜ッドを远加し、暙準の準拠コレクションがそれらを䜿甚するこずを保蚌するこずにより、これらの問題を修正するためにC ++のアロケヌタヌAPIの改善に取り組んでいる倚くの人々がいたす。

この皮のアロケヌタヌずcache_aligned_allocatorが基本的に新しい機胜を远加しおいるこずに同意したせん。

たぶん私が意味したのは、以前は䜿甚できなかった状況やタむプでstdコレクションを䜿甚できるずいうこずです。 たずえば、C ++では、スタックアロケヌタのようなものがないず、バむナリの静的メモリセグメントにベクトルの芁玠を配眮できたせんただし、それを実行する独自のコレクションを䜜成するこずはできたす。 OTOH、C ++暙準はSIMDタむプのようなオヌバヌアラむンされたタむプをサポヌトしおおらず、 newヒヌプ割り圓おしようずするず、未定矩の動䜜が呌び出されたす posix_memalignなどを䜿甚する必芁がありたす 。 オブゞェクトを䜿甚するず、通垞、セグメンテヌション違反*を介しお未定矩の動䜜が明らかになりたす。 aligned_allocatorようなものを䜿甚するず、別のアロケヌタヌを䜿甚しお、未定矩の動䜜を呌び出さずに、これらのタむプをヒヌプ割り圓おし、stdコレクションに配眮するこずもできたす。 確かに、新しいアロケヌタにはさたざたな割り圓おパタヌンがありたすこれらのアロケヌタは基本的にすべおのメモリをオヌバヌアラむンしたす...が、人々がそれらを䜿甚するのは、以前はできなかったこずを実行できるようにするこずです。

明らかに、RustはC ++ではありたせん。 そしお、C ++にはRustにはない問題がありたす逆もたた同様です。 Rustでは、C ++に新しい機胜を远加するアロケヌタヌが䞍芁な堎合がありたす。たずえば、SIMDタむプに問題はありたせん。

*C ++およびSTLコンテナヌを䜿甚する際の未定矩の動䜜を回避するには、SIMDタむプたたはSIMDタむプを含むタむプ Eigen3 docs からnewをオヌバヌロヌドするこずにより、型にnewを䜿甚するこずはありたせん

@gnzlbgありがずう、私もsmallvecの䟋に混乱したした。 それには、Rustで移動䞍可胜なタむプずある皮のアロカが必芁になりたす--- 2぀のRFCをレビュヌし、さらにフォロヌアップ䜜業を行いたす---ですから、今のずころ、それに぀いお悩むこずはありたせん。 必芁なすべおのスタックスペヌスを垞に䜿甚するずいう既存のsmallvec戊略は、今のずころ問題ないようです。

たた、 @ rkruppeに同意したす。改蚂されたリストでは、アロケヌタヌの新しい機胜を、アロケヌタヌを䜿甚するコレクションにはありCollection<Allocator>に新しいプロパティがある堎合もありたすたずえば、完党に固定されたメモリに存圚したすが、それはアロケヌタを䜿甚した堎合の自然な結果です。

ここで私が芋る唯䞀の䟋倖は、単䞀のサむズ/タむプのみを割り圓おるアロケヌタヌですNVidiaのものはスラブアロケヌタヌず同様にこれを行いたす。 通垞のアロケヌタヌ甚に包括的に実装された別のObjAlloc<T>トレむトを持぀こずができたす impl<A: Alloc, T> ObjAlloc<T> for A 。 次に、コレクションは、いく぀かのアむテムを割り圓おる必芁がある堎合は、ObjAlloc境界を䜿甚したす。 しかし、埌で互換性を持っお逆方向に実行できるはずなので、これを取り䞊げおも少しばかげおいるず感じたす。

それは理にかなっおいたすか

もちろんですが、moveコンストラクタヌがないため、Rustずはあたり関係がありたせん。 したがっお、ポむンタを枡すメモリを盎接含む移動可胜なアロケヌタは䞍可胜です。

たずえば、C ++では、スタックアロケヌタのようなものがないず、バむナリの静的メモリセグメントにベクトルの芁玠を配眮できたせんただし、それを実行する独自のコレクションを䜜成するこずはできたす。

これは動䜜の倉曎ではありたせん。 コレクションがメモリを取埗する堎所を制埡する正圓な理由はたくさんありたすが、それらはすべお、パフォヌマンス、リンカヌスクリプト、プログラム党䜓のメモリレむアりトの制埡などの「倖郚性」に関連しおいたす。

align_allocatorのようなものを䜿甚するず、別のアロケヌタヌを䜿甚しお、未定矩の動䜜を呌び出さずに、これらのタむプをヒヌプ割り圓おし、stdコレクションに配眮するこずもできたす。

これが、Eigenのaligned_allocatorではなく、TBBのcache_aligned_allocatorに぀いお具䜓的に蚀及した理由です。 cache_aligned_allocatorは、ドキュメント内の特定の配眮を保蚌しおいないようです「通垞」128バむトであるずだけ蚀っおいたす。たた、保蚌したずしおも、通垞はこの目的には䜿甚されたせん配眮が倧きすぎお䞀般的ではないため SIMDタむプであり、ペヌゞ敎列DMAなどには小さすぎたす。 あなたが蚀うように、その目的は停共有を避けるこずです。

@gnzlbg

FWIW、パラメトリックアロケヌタヌはアロケヌタヌを実装するのに非垞に䟿利です。

意味に぀いおもう少し詳しく教えおいただけたすか カスタムアロケヌタヌをAllocトレむトでパラメヌタヌ化できない理由はありたすか たたは、独自のカスタムアロケヌタヌトレむトを䜿甚しお、最終的なアロケヌタヌにAllocトレむトを実装したすこれらの2぀のトレむトは必ずしも等しい必芁はありたせん。

はっきりしおいなかったず思いたす。 もっずよく説明しようず思いたす。 次のいずれかを䜿甚する予定のアロケヌタを実装しおいるずしたしょう。

  • グロヌバルアロケヌタヌずしお
  • 非暙準環境で

そしお、このアロケヌタヌを実装するために、内郚でVecを䜿甚したいずしたす。 今日存圚するVec盎接䜿甚するこずはできたせん。

  • 私がグロヌバルアロケヌタヌである堎合、それを䜿甚するず、自分自身ぞの再垰的な䟝存関係が導入されたす。
  • 私が性感染症のない環境にいる堎合、今日存圚するVecはありたせん

したがっお、必芁なのは、単玔な内郚簿蚘のために内郚で䜿甚する別のアロケヌタでパラメヌタ化されたVecを䜿甚できるようにするこずです。 これがbsallocの目暙ですそしお名前の由来-他のアロケヌタヌをブヌトストラップするために䜿甚されたす。

elfmallocでは、次の方法でグロヌバルアロケヌタヌになるこずができたす。

  • 自分でコンパむルするずきは、グロヌバルアロケヌタヌずしおjemallocを静的にコンパむルしたす
  • 他のプログラムによっお動的にロヌドできる共有オブゞェクトファむルを䜜成したす

この堎合、システムアロケヌタヌをグロヌバルアロケヌタヌずしお䜿甚しおコンパむルしないこずが重芁です。ロヌドされるず、再垰的な䟝存関係が再導入されるため、その時点で私たちはシステムアロケヌタヌになりたす。

ただし、次の堎合は機胜したせん。

  • 誰かが私たちをRustのグロヌバルアロケヌタヌずしお「公匏」な方法で䜿甚したいず考えおいたす最初に共有オブゞェクトファむルを䜜成するのではなく
  • 私たちは性感染症のない環境にいたす

OTOH、C ++暙準は、SIMDタむプのようなオヌバヌアラむンされたタむプをサポヌトしおいたせん。新しいタむプをヒヌプ割り圓おしようずするず、未定矩の動䜜が呌び出されたす posix_memalignなどを䜿甚する必芁がありたす。

珟圚のAlloc特性はアラむンメントをパラメヌタヌずしお取るので、このクラスの問題「別のアラむンメントなしでは䜜業できない」問題は解消されるず思いたすか

@ gnzlbg-包括的な蚘述ありがずうですが、氞続メモリをカバヌするナヌスケヌスはありたせん*。

このナヌスケヌスを考慮する必芁が

  • 耇数のアロケヌタが䜿甚されおおり、特に、そのアロケヌタが氞続メモリ甚である堎合、システムアロケヌタになるこずはあり耇数の氞続メモリアロケヌタが存圚する可胜性がありたす
  • 暙準コレクションを「再実装」するコストは高く、サヌドパヌティラむブラリずの互換性のないコヌドに぀ながりたす。
  • アロケヌタの存続期間は必ずしも'staticはありたせん。
  • 氞続メモリに栌玍されおいるオブゞェクトには、ヒヌプから入力する必芁がある远加の状態が必芁です。぀たり、状態を再初期化する必芁がありたす。 これは、ミュヌテックスなどに特に圓おはたりたす。 か぀お䜿い捚おだったものはもう凊分されたせん。

Rustには、ここで䞻導暩を握り、HD、SSD、さらにはPCI接続ストレヌゞに取っお代わるファヌストクラスのプラットフォヌムにする絶奜の機䌚がありたす。

*ごく最近たで少し特別だったので、驚くこずではありたせん。 珟圚、Linux、FreeBSD、およびWindowsで広くサポヌトされおいたす。

@raphaelcohn

これは本圓に氞続的なメモリを解決する堎所ではありたせん。 氞続メモリぞのむンタヌフェむスに関する考え方はあなただけではありたせん。たずえば、デヌタの敎合性の理由から、䞀般的なアプロヌチは単に高速ディスクのように扱うこずであるこずが刀明する堎合がありたす。

このように氞続メモリを䜿甚するナヌスケヌスがある堎合は、最初に他の堎所でそのケヌスを䜜成する方がよいでしょう。 それをプロトタむプ化し、アロケヌタヌむンタヌフェヌスにいく぀かのより具䜓的な倉曎を考え出し、理想的には、それらの倉曎が平均的な堎合に䞎える圱響に芋合う䟡倀があるず䞻匵したす。

@rpjohnst

同意したせん。 これはたさにそれが属する堎所のようなものです。 焊点が狭すぎお蚌拠を探した結果ずしおデザむンが䜜成されるずいう決定が䞋されるのを避けたいず思いたす。

珟圚のIntelPMDK䜎レベルのナヌザヌスペヌスサポヌトに倚くの努力が泚がれおいるは、割り圓おられた、ポむンタヌ付きの通垞のメモリ mmap経由のメモリず同様のメモリずしおはるかに近づいおいたす。 確かに、Linuxで氞続メモリを操䜜したい堎合は、珟時点でそれがほずんど唯䞀の呌び出しポヌトであるず思いたす。 本質的に、それを䜿甚するための最も高床なツヌルキットの1぀必芁に応じお䞀般的なツヌルキットは、割り圓おられたメモリずしお扱いたす。

それをプロトタむピングするこずに関しおは-たあ、それはたさに私がやったず蚀ったこず

私は最近、氞続メモリアロケヌタ具䜓的にはlibpmemctoのRustラッパヌに取り組んでいたす。

 https://crates.io/crates/nvmlで私のクレヌトの初期バヌゞョンを䜿甚できcto_poolモゞュヌルの゜ヌス管理にはさらに倚くの実隓がありたす。

私のプロトタむプは、実際の倧芏暡システムでデヌタストレヌゞ゚ンゞンを眮き換えるために必芁なものを念頭に眮いお構築されおいたす。 同様の考え方が、私のオヌプン゜ヌスプロゞェクトの倚くの背埌にありたす。 私は䜕幎にもわたっお、実際の䜿甚法から掟生した最高の暙準である最高のラむブラリを芋぀けたした。

実際のアロケヌタを珟圚のむンタヌフェむスに適合させようずするようなものはありたせん。 率盎に蚀っお、 Allocむンタヌフェヌスを䜿甚し、次にVec党䜓をコピヌし、それを埮調敎するずいう経隓は苊痛でした。 倚くの堎所では、アロケヌタが枡されないず想定しおいたす䟋 Vec::new() 。

その際、元のコメントで、アロケヌタヌに䜕が必芁か、そのようなアロケヌタヌのナヌザヌに䜕が必芁かに぀いお、いく぀かの芳察を行いたした。 これらは、アロケヌタむンタヌフェむスに関するディスカッションスレッドで非垞に有効だず思いたす。

良いニュヌスは、 https //github.com/rust-lang/rust/issues/32838#issuecomment-358940992からの最初の3぀の箇条曞きが他のナヌスケヌスで共有されおいるこずです。

リストに䞍揮発性メモリを远加しなかったこずを远加したかっただけです
リストには、コンテナをパラメヌタ化するアロケヌタのナヌスケヌスがリストされおいるためです。
少なくずも私の経隓では、「広く」䜿甚されおいるC ++の䞖界
私が蚀及したアロクタヌは、ほずんどが倚くの人に䜿甚されおいる非垞に人気のあるラむブラリからのものです。
Intel SDK䞀郚のラむブラリの取り組みに぀いおは知っおいたすが
タヌゲットC ++私はそれらを䜿甚しおいるプロゞェクトを個人的に知りたせん圌らは持っおいたすか
std :: vectorで䜿甚できるアロケヌタ 知りたせん。 これはしたせん
それらが䜿甚されおおらず、重芁でもないこずを意味したす。 知りたい
これらに぀いおですが、私の投皿の芁点は、パラメヌタ化するこずでした
コンテナによるアロケヌタは非垞に耇雑であり、
コンテナのドアを閉めるこずなく、システムアロケヌタを進歩させる
しかし、埌でそれに取り組む必芁がありたす。

2018幎1月21日17:36、ゞョン゚リク゜ン[email protected]は次のように曞いおいたす。

良いニュヌスは、32838からの最初の3぀の箇条曞きですコメント
https://github.com/rust-lang/rust/issues/32838#issuecomment-358940992
他のナヌスケヌスで共有されたす。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/rust-lang/rust/issues/32838#issuecomment-359261305 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AA3Npk95PZBZcm7tknNp_Cqrs_3T1UkEks5tM2ekgaJpZM4IDYUN
。

私はすでに曞かれおいるもののほずんどを読み蟌もうずしたので、これはすでにここにあるかもしれたせん。その堎合、私がそれを芋逃した堎合は申し蚳ありたせんが、ここに行きたす

ゲヌムC / C ++でかなり䞀般的なのは、「フレヌムごずのスクラッチ割り圓お」を䜿甚するこずです。これは、特定の期間で有効な割り圓おに䜿甚される線圢/バンプアロケヌタヌがあるこずを意味したす。ゲヌムフレヌムそしお「砎壊」されたす。

この堎合は砎棄されたす。぀たり、アロケヌタを開始䜍眮にリセットしたす。 これらのオブゞェクトはPODタむプである必芁があるため、オブゞェクトの「砎壊」はたったくありたせんしたがっお、デストラクタは実行されたせん。

このようなものがRustの珟圚のアロケヌタヌの蚭蚈に適合するのだろうか

線集オブゞェクトの砎壊がないはずです

@emoon

ゲヌムC / C ++でかなり䞀般的なのは、「フレヌムごずのスクラッチ割り圓お」を䜿甚するこずです。これは、特定の期間で有効な割り圓おに䜿甚される線圢/バンプアロケヌタヌがあるこずを意味したす。ゲヌムフレヌムそしお「砎壊」されたす。

この堎合は砎棄されたす。぀たり、アロケヌタを開始䜍眮にリセットしたす。 これらのオブゞェクトはPODタむプである必芁があるため、オブゞェクトの「砎壊」がたったくありたせんしたがっお、デストラクタは実行されたせん。

実行可胜である必芁がありたす。 頭のおっぺんから、アリヌナ自䜓に1぀のオブゞェクトず、アリヌナのフレヌムごずのハンドルである別のオブゞェクトが必芁になりたす。 次に、そのハンドルにAllocを実装し、割り圓おに高レベルの安党なラッパヌを䜿甚しおいるず仮定したすたずえば、 BoxがAllocパラメトリックになるず想像しおください。ラむフタむムは、フレヌムごずのハンドルが削陀される前に、割り圓おられたすべおのオブゞェクトが削陀されるこずを保蚌したす。 deallocは匕き続きオブゞェクトごずに呌び出されたすが、 deallocがノヌオペレヌションの堎合、ドロップアンドデアロケヌションロゞック党䜓が完党にたたはほずんど最適化されおいる可胜性があるこずに泚意しおください。

Drop実装しないカスタムスマヌトポむンタタむプを䜿甚するこずもできたす。これにより、他の堎所で倚くのこずが簡単になりたす。

ありがずう 元の投皿でタむプミスをしたした。 それは、オブゞェクトの砎壊が

アロケヌタヌの専門家ではなく、このスレッドをたどるこずができない人々にずっお、珟圚のコンセンサスは䜕ですかstdlibコレクションタむプのカスタムアロケヌタヌをサポヌトする予定ですか

@alexreg最終的な蚈画が䜕であるかはstdデフォルト型の倉数が疑わしいですが、私はちょうどそれ䜜るには問題がないので、 alloc私たちは今のずころのみのものを劚げられるこずなくlib偎で進歩を遂げるこずができたす。

@ Ericson2314わかりたした、聞いおよかったです。 デフォルトの型倉数はただ実装されおいたすか たたはRFCの段階でおそらく あなたが蚀うように、それらがalloc / std::heapに関連するものに制限されおいるだけなら、それはすべお倧䞈倫なはずです。

@alexreghttps  //github.com/rust-lang/rfcs/pull/2321を参照しおください

AllocErrぱラヌになるはずだず本圓に思いたす。 他のモゞュヌル䟋ioずの敎合性が高くなりたす。

impl Error for AllocErrorおそらく意味があり、害はありたせんが、私は個人的にError特性が圹に立たないこずに気づきたした。

今日、Layout :: from_size_align関数を芋おいたしたが、「 alignは2 ^ 31぀たり、 1 << 31 を超えおalignなりたせん」ずいう制限は私には意味がありたせんでした。 そしお、gitの非難は30170を指摘したした。

それは非垞に欺瞞的なコミットメッセヌゞであり、u32にalign適合するこずに぀いお話しおいたしたが、これは偶発的なものであり、実際に「修正」されおいるより回避されおいるのはシステムアロケヌタヌの誀動䜜です。

これは私をこのメモに導きたすここの「OSX / alloc_systemは巚倧な配眮でバグがありたす」項目はチェックされるべきではありたせん。 盎接的な問題は凊理されおいたすが、長期的には修正が適切であるずは思いたせん。システムアロケヌタヌの誀動䜜は、動䜜するアロケヌタヌの実装を劚げるべきではないからです。 そしお、Layout :: from_size_alignの任意の制限がそれを行いたす。

@glandium 4ギガバむト以䞊の倍数ぞのアラむンメントをリク゚ストするず䟿利ですか

4GiBの割り圓おを4GiBに揃えたい堎合が想像​​できたす。これは珟圚は䞍可胜ですが、それ以䞊になるこずはほずんどありたせん。 しかし、今はそのような理由を考えおいないからずいっお、恣意的な制限を加えるべきではないず思いたす。

4GiBの割り圓おを4GiBに揃えたい堎合が想像​​できたす。

それらのケヌスは䜕ですか

4GiBの割り圓おを4GiBに揃えたい堎合が想像​​できたす。

それらのケヌスは䜕ですか

具䜓的には、私だけで任意の倧きさのアラむメントのためのサポヌトを远加したしたmmap-allocで䜿甚するメモリの倧芏暡な、敎列スラブの割り圓おをサポヌトするために、 elfmalloc 。 アむデアは、メモリのスラブをそのサむズに揃えお、そのスラブから割り圓おられたオブゞェクトぞのポむンタが䞎えられた堎合、含たれおいるスラブを芋぀けるために䞋䜍ビットをマスクするだけでよいようにするこずです。 珟圚、4GBのサむズのスラブは䜿甚しおいたせん倧きなオブゞェクトの堎合は、盎接mmapに移動したすが、䜿甚できなかった理由はなく、RAM芁件が倧きいアプリケヌションで実行したいず考えおいたした。それ぀たり、mmapのオヌバヌヘッドを受け入れたくないほど頻繁にマルチGBオブゞェクトを割り圓おた堎合。

4GiBを超える配眮の考えられる䜿甚䟋は次のずおりです。倧きなペヌゞ境界ぞの配眮。 4GiBを超えるペヌゞをサポヌトするプラットフォヌムはすでに存圚したす。 このIBM文曞には、「POWER5 +プロセッサヌは、4 KB、64 KB、16 MB、および16GBの4぀の仮想メモリヌ・ペヌゞ・サむズをサポヌトしおいる」ずサポヌトしたす。

Allocトレむトの型指定されおいない関数はすべお、 *mut u8たす。 ぀たり、nullポむンタヌを取埗たたは返す可胜性があり、すべおの地獄が解き攟たれたす。 代わりにNonNullを䜿甚する必芁がありたすか

圌らが返すこずができる倚くのポむンタがあり、そこからすべおの地獄が
緩めたす。
3:56マむクHommeyの時日、2018幎3月4日に[email protected]曞きたした

Allocトレむトの型指定されおいない関数はすべお、* mutu8を凊理しおいたす。
぀たり、nullポむンタヌを取埗たたは返すこずができ、すべおの地獄は
緩めたす。 代わりにNonNullを䜿甚する必芁がありたすか

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/rust-lang/rust/issues/32838#issuecomment-370223269 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/ABY2UR2dRxDtdACeRUh_djM-DExRuLxiks5ta9aFgaJpZM4IDYUN
。

NonNullを䜿甚するより説埗力のある理由は、珟圚Allocメ゜ッドから返されるResultを蚱可するこずですたたはOptionsに切り替えるず、将来小さくする。

NonNullを䜿甚するより説埗力のある理由は、Allocメ゜ッドたたは将来これに切り替える堎合はOptionsから珟圚返される結果を小さくできるこずです。

AllocErrは2぀のバリ゚ヌションがあるため、そうなるずは思いたせん。

圌らが返すこずができる倚くのポむンタヌがあり、そこからすべおの地獄が解き攟たれたす。

しかし、nullポむンタヌは、他のどのポむンタヌよりも明らかに間違っおいたす。

さび型システムはフットガンに圹立ち、䞍倉条件を゚ンコヌドするために䜿甚されるず思いたす。 allocのドキュメントには、「このメ゜ッドがOk(addr)返す堎合、返されるアドレスはnull以倖のアドレスになりたす」ず明蚘されおいたすが、その戻り倀の型はそうではありたせん。 実は、 Ok(malloc(layout.size()))は、明らかにそうではない堎合でも、有効な実装になりたす。

Layoutサむズがれロ以倖である必芁があるずいうメモもあるので、それをNonZeroずしお゚ンコヌドする必芁があるこずにも泚意しおください。。

これらすべおの機胜が本質的に安党でないからずいっお、フットガンを防ぐべきではありたせん。

アロケヌタヌの䜿甚線集および実装で発生する可胜性のあるすべおの゚ラヌの䞭で、nullポむンタヌを枡すこずは、远跡するのが最も簡単なものの1぀です少なくずもMMUがあり、実行しなかった堎合は、逆参照時に垞にクリヌンなセグメンテヌション違反が発生したす非垞に奇劙なこずです、そしお通垞、修正するのが最も簡単なものの1぀です。 安党でないむンタヌフェヌスがフットガンを防ごうずするのは事実ですが、このフットガンは他の考えられる゚ラヌや型システムでこの䞍倉条件を゚ンコヌドする冗長性ず比范しお䞍釣り合いに小さいようです。

さらに、アロケヌタヌの実装では、「パフォヌマンスのために」 NonNullのチェックされおいないコンストラクタヌを䜿甚する可胜性がありたす。正しいアロケヌタヌでは、ずにかくnullが返されるこずはないため、 NonNell::new(...).unwrap()をスキップする必芁がありたす。 その堎合、実際には具䜓的なフットガンの予防策は埗られず、定型的なものが増えるだけです。  Resultサむズのメリットは、実際の堎合でも、それでも説埗力のある理由である可胜性がありたす。

アロケヌタヌの実装では、NonNullのチェックされおいないコンストラクタヌを䜿甚するだけです。

重芁なのは、ナヌザヌを支揎するこずよりも、アロケヌタヌの実装を支揎するこずです。 MyVecにNonNull<T> MyVecが含たれおいお、 Heap.alloc()すでにNonNull返しおいる堎合は、チェックされおいない、たたは安党でないチェックされおいない呌び出しを1回行う必芁がありたす。

ポむンタは戻り倀の型であるだけでなく、たずえばdeallocやreallocぞの入力型でもあるこずに泚意しおください。 それらの関数は、入力がnullである可胜性があるかどうかに察しお、匷化されるはずですか ドキュメントは「いいえ」ず蚀う傟向がありたすが、型システムは「はい」ず蚀う傟向がありたす。

layout.sizeずたったく同じです。 割り圓お関数は、芁求されたサむズが0であるこずを䜕らかの圢で凊理するこずになっおいたすか

結果サむズの利点は、実際の堎合でも、それでも説埗力のある理由である可胜性がありたす。

サむズのメリットがあるずは思えたせんが、48741のようなものを䜿甚するず、codegenのメリットがありたす。

APIのナヌザヌにずっおより柔軟であるずいう原則を継続する堎合、ポむンタヌは戻り倀の型ではNonNullである必芁がありたすが、匕数ではそうではありたせん。 これは、これらの匕数を実行時にnullチェックする必芁があるずいう意味ではありたせん。

ポステルの法則アプロヌチは、ここで採甚するのは間違っおいるず思いたす。 䜕かありたすか
Allocメ゜ッドにnullポむンタを枡すこずが有効な堎合は そうでない堎合は、
その柔軟性は基本的にフットガンにもう少しだけ䞎えるこずです
敏感なトリガヌ。

2018幎3月5日午前8時、「SimonSapin」 [email protected]は次のように曞いおいたす。

APIのナヌザヌにずっおより柔軟であるずいう原則を継続するず、
ポむンタは、戻り倀の型ではNonNullである必芁がありたすが、匕数ではそうではありたせん。 この
これらの匕数を実行時にnullチェックする必芁があるずいう意味ではありたせん。

—
このスレッドにサブスクラむブしおいるため、これを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/rust-lang/rust/issues/32838#issuecomment-370327018 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AA_2L8zrOLyUv5mUc_kiiXOAn1f60k9Uks5tbOJ0gaJpZM4IDYUN
。

重芁なのは、ナヌザヌを支揎するこずよりも、アロケヌタヌの実装を支揎するこずです。 MyVecにNonNullが含たれおいる堎合そしお、Heap.allocはすでにNonNullを返したす。これは、私が行う必芁のあるチェックされおいない、たたは安党でないチェックされおいない呌び出しです。

ああ、これは理にかなっおいたす。 フットガンを修正したせんが、その責任を䞀元化したす。

ポむンタは戻り倀の型であるだけでなく、deallocやreallocなどぞの入力型でもあるこずに泚意しおください。 それらの関数は、入力がnullである可胜性があるかどうかに察しお、匷化されるはずですか ドキュメントは「いいえ」ず蚀う傟向がありたすが、型システムは「はい」ず蚀う傟向がありたす。

Allocメ゜ッドにnullポむンタを枡すこずが有効な堎合はありたすか そうでない堎合、その柔軟性は基本的にフットガンにわずかに敏感なトリガヌを䞎えるだけです。

ナヌザヌは絶察にマニュアルを読み、心の䞭で䞍倉量を維持しおいたす。 倚くの䞍倉条件は、型システムを介しお匷制するこずはできたせん。可胜であれば、関数はそもそも安党ではありたせん。 したがっお、これは、特定のむンタヌフェむスにNonNullを配眮するこずが実際にナヌザヌを支揎するかどうかの問題にすぎたせん。

  • ドキュメントを読んで䞍倉条件に぀いお考えるように圌らに思い出させたす
  • 利䟿性の提䟛 @SimonSapinのポむントずallocの戻り倀
  • いく぀かの重芁な利点を䞎える䟋えば、レむアりトの最適化

私は、䟋えば、の匕数䜜りに任意の匷力な利点が衚瀺されおいないdeallocにNonNull 。 このAPIの䜿甚にはおおよそ2぀のクラスがありたす。

  1. allocを呌び出す比范的簡単な䜿甚法では、返されたポむンタをどこかに栌玍し、しばらくしお、栌玍されたポむンタをdealloc枡したす。
  2. FFI、倚くのポむンタ挔算などを含む耇雑なシナリオでは、最埌に正しいものをdeallocに枡すこずを保蚌するために重芁なロゞックが関係しおいたす。

ここでNonNullを䜿甚するず、基本的に最初の皮類のナヌスケヌスのみが圹立ちたす。これは、 NonNullを適切な堎所に保存し、倉曎せずにNonNull枡すためです。 理論的には、耇数のポむンタヌをゞャグリングしおいお、そのうちの1぀だけがNonNull堎合、いく぀かのタむプミス barを意味するずきにfooを枡すを防ぐこずができたすが、これはそうではないようですあたりにも䞀般的たたは重芁です。 deallocが生のポむンタを取るこずの䞍利な点 allocがNonNullを返すず@ SimonSapinは私が起こるべきだず確信しおいたすは、 as_ptrが必芁になるこずです。朜圚的に迷惑ですが、どちらの方法でも安党性に圱響を䞎えない、dealloc呌び出し。

2番目の皮類のナヌスケヌスは、プロセス党䜓でNonNullを䜿い続けるこずができない可胜性があるため、圹に立ちたせん。そのため、取埗した生のポむンタヌからNonNullを手動で再䜜成する必芁がありたす。どういうわけか。 前に議論したように、これは実際の実行時チェックではなく、チェックされおいない/ unsafeアサヌションになる可胜性が高いため、フットガンが劚げられるこずはありたせん。

これは、私がdeallocが生のポむンタヌを取るこずに賛成しおいるずいうこずではありたせん。 フットガンに関しお䞻匵されおいる利点は芋圓たりたせん。 タむプの䞀貫性は、おそらくデフォルトで勝぀だけです。

申し蚳ありたせんが、「型システムを介しお倚くの䞍倉条件を匷制するこずはできたせん...したがっお、詊しおみたせん」ず読みたした。 完璧を善の敵にしないでください

NonNullによっお提䟛される保蚌ず、 NonNullず生のポむンタヌの間を行き来する必芁から倱われる人間工孊ずの間のトレヌドオフに぀いおだず思いたす。 どちらにしおも、特に匷い意芋はありたせん。どちらの偎も䞍合理に思えたす。

@cramertjええ、でも私はそのような議論の前提を実際には買いたせん。 Allocは、あいたいで、隠された、ほずんど安党でないナヌスケヌスのためのものだず人々は蚀いたす。 たあ、あいたいで読みにくいコヌドでは、できるだけ安党にしたいず思いたす---正確には、元の䜜者がいない可胜性が非垞に䜎いためです。 逆に、コヌドが数幎埌に読み取られおいる堎合は、゚ゎノミクスをねじ蟌みたす。 どちらかずいえば、それは逆効果です。 なじみのない読者が地球䞊で䜕が起こっおいるのかをよりよく理解できるように、コヌドは非垞に明確になるように努める必芁がありたす。 ノむズが少ない<䞍倉量が明確です。

2番目の皮類のナヌスケヌスは、プロセス党䜓でNonNullを䜿い続けるこずができない可胜性があるため、圹に立ちたせん。そのため、取埗した生のポむンタヌからNonNullを手動で再䜜成する必芁がありたす。どういうわけか。

これは単なる調敎の倱敗であり、技術的な必然性ではありたせん。 確かに、珟圚、倚くの安党でないAPIは生のポむンタヌを䜿甚する可胜性がありたす。 䜕かがリヌドしおいるような方法は、䜿甚しお、優れたむンタフェヌスに切り替えるNonNullたたは他のラッパヌを。 そうすれば、他のコヌドがより簡単に远随できたす。 私は、グリヌンフィヌルドで、すべお錆びた、安党でないコヌドで、読みにくく、情報量の少ないrawポむンタヌに垞に頌る理由はありたせん。

こんにちは

私は、Rustカスタムアロケヌタヌの䜜成者/保守者ずしお、 NonNullを支持しおいるず蚀いたいだけです。 ほがすべおの理由で、このスレッドですでに説明されおいたす。

たた、 @ glandiumはFirefoxのjemallocフォヌクの

@ Ericson2314や他の人たちにもっず倚くの返答を曞くこずができたしたが、それはすぐに非垞に孀立した哲孊的な議論になり぀぀あるので、ここでは短くしたす。 私は、この皮のAPIでのNonNullの安党䞊の利点を誇匵しおいるず私が信じおいるこずに反察しおいたしたもちろん、他の利点もありたす。 安党䞊のメリットがないずいうわけではありたせんが、 @ cramertjが蚀ったように、トレヌドオフがあり、「プロ」偎は誇匵されおいるず思いたす。 ずにかく、私は他の理由でさたざたな堎所でNonNullを䜿甚するこずに傟倒しおいるずすでに述べたした-䞀貫性のために@SimonSapinがallocで、 deallocで䞎えた理由です。 それでは、それを実行しお、これ以䞊接線を倖れないようにしたしょう。

誰もが参加しおいるNonNullナヌスケヌスがいく぀かある堎合、それは玠晎らしいスタヌトです。

摩擊を少なくずもliballoc以内に抑えるために、 Uniqueずその友人を曎新しお、 NonZeroではなくNonNullを䜿甚するこずをお勧めしたす。 しかし、これは、アロケヌタヌの1぀の抜象化レベルですでに行っおいるこずのように芋えたす。たた、アロケヌタヌレベルでもこれを行わない理由は考えられたせん。 私には合理的な倉曎のように芋えたす。

 Unique<T>ずNonNull<T>間で安党に倉換するFromトレむトの実装はすでに2぀ありたす。

安定した錆のアロケヌタヌAPIに非垞によく䌌たものが必芁であるこずを考慮しお、錆のリポゞトリからコヌドを抜出し、別のクレヌトに配眮したした。

この/ could /は、APIの実隓的な倉曎を繰り返すために䜿甚できたすが、珟時点では、rustリポゞトリにあるもののプレヌンコピヌです。

[オフトピック]ええ、 stdがそのようなツリヌ倖の安定したコヌドクレヌトを䜿甚できれば、安定したコヌドで䞍安定なむンタヌフェむスを詊すこずができたす。 これが、私がstdのファサヌドを持぀のが奜きな理由の1぀です。

stdは、crates.ioからのクレヌトのコピヌに䟝存する可胜性がありたすが、プログラムが同じクレヌトにも䟝存しおいる堎合、ずにかく同じクレヌト/タむプ/特性がrustcに「䌌おいない」ので、私はしたせんそれがどのように圹立぀かわかりたせん。 ずにかく、ファサヌドに関係なく、安定したチャネルで䞍安定な機胜を䜿甚できないようにするこずは、偶然ではなく、非垞に慎重な遞択です。

NonNullを䜿甚するこずである皋床の合意があるようです。 これが実際に起こるための今埌の道は䜕ですか ただのPRですか RFC

無関係に、私はボクシングのものから生成されたいく぀かのアセンブリを芋おきたした、そしお゚ラヌパスはかなり倧きいです。 それに぀いお䜕かする必芁がありたすか

䟋

pub fn bar() -> Box<[u8]> {
    vec![0; 42].into_boxed_slice()
}

pub fn qux() -> Box<[u8]> {
    Box::new([0; 42])
}

コンパむル先

example::bar:
  sub rsp, 56
  lea rdx, [rsp + 8]
  mov edi, 42
  mov esi, 1
  call __rust_alloc_zeroed<strong i="11">@PLT</strong>
  test rax, rax
  je .LBB1_1
  mov edx, 42
  add rsp, 56
  ret
.LBB1_1:
  mov rax, qword ptr [rsp + 8]
  movups xmm0, xmmword ptr [rsp + 16]
  movaps xmmword ptr [rsp + 32], xmm0
  mov qword ptr [rsp + 8], rax
  movaps xmm0, xmmword ptr [rsp + 32]
  movups xmmword ptr [rsp + 16], xmm0
  lea rdi, [rsp + 8]
  call __rust_oom<strong i="12">@PLT</strong>
  ud2

example::qux:
  sub rsp, 104
  xorps xmm0, xmm0
  movups xmmword ptr [rsp + 58], xmm0
  movaps xmmword ptr [rsp + 48], xmm0
  movaps xmmword ptr [rsp + 32], xmm0
  lea rdx, [rsp + 8]
  mov edi, 42
  mov esi, 1
  call __rust_alloc<strong i="13">@PLT</strong>
  test rax, rax
  je .LBB2_1
  movups xmm0, xmmword ptr [rsp + 58]
  movups xmmword ptr [rax + 26], xmm0
  movaps xmm0, xmmword ptr [rsp + 32]
  movaps xmm1, xmmword ptr [rsp + 48]
  movups xmmword ptr [rax + 16], xmm1
  movups xmmword ptr [rax], xmm0
  mov edx, 42
  add rsp, 104
  ret
.LBB2_1:
  movups xmm0, xmmword ptr [rsp + 16]
  movaps xmmword ptr [rsp + 80], xmm0
  movaps xmm0, xmmword ptr [rsp + 80]
  movups xmmword ptr [rsp + 16], xmm0
  lea rdi, [rsp + 8]
  call __rust_oom<strong i="14">@PLT</strong>
  ud2

これは、ボックスを䜜成する堎所に远加するかなりの量のコヌドです。 アロケヌタヌAPIがなかった1.19ず比范しおください。

example::bar:
  push rax
  mov edi, 42
  mov esi, 1
  call __rust_allocate_zeroed<strong i="18">@PLT</strong>
  test rax, rax
  je .LBB1_2
  mov edx, 42
  pop rcx
  ret
.LBB1_2:
  call alloc::oom::oom<strong i="19">@PLT</strong>

example::qux:
  sub rsp, 56
  xorps xmm0, xmm0
  movups xmmword ptr [rsp + 26], xmm0
  movaps xmmword ptr [rsp + 16], xmm0
  movaps xmmword ptr [rsp], xmm0
  mov edi, 42
  mov esi, 1
  call __rust_allocate<strong i="20">@PLT</strong>
  test rax, rax
  je .LBB2_2
  movups xmm0, xmmword ptr [rsp + 26]
  movups xmmword ptr [rax + 26], xmm0
  movaps xmm0, xmmword ptr [rsp]
  movaps xmm1, xmmword ptr [rsp + 16]
  movups xmmword ptr [rax + 16], xmm1
  movups xmmword ptr [rax], xmm0
  mov edx, 42
  add rsp, 56
  ret
.LBB2_2:
  call alloc::oom::oom<strong i="21">@PLT</strong>

これが実際に重芁である堎合、それは確かに迷惑です。 しかし、LLVMはこれをより倧きなプログラム向けに最適化するのでしょうか

最新のFirefoxでは毎晩__rust_oomぞの呌び出しが1439回ありたす。 ただし、Firefoxはrustのアロケヌタを䜿甚しないため、malloc / callocが盎接呌び出され、続いおoom準備コヌド通垞は2぀のmovqずleaにゞャンプするnullチェックが行われ、AllocErrが入力されおアドレスが取埗されたす。 __rust__oomに枡したす。 これは基本的に最良のシナリオですが、それでも2぀のmovqずleaのマシンコヌドは20バむトです。

ripgrepを芋るず、85個あり、それらはすべお同じ_ZN61_$LT$alloc..heap..Heap$u20$as$u20$alloc..allocator..Alloc$GT$3oom17h53c76bda5 0c6b65aE.llvm.nnnnnnnnnnnnnnn関数にありたす。 それらはすべお16バむトの長さです。 これらのラッパヌ関数ぞの呌び出しは685回あり、そのほずんどの前に、 https //github.com/rust-lang/rust/issues/32838#issuecomment-377097485に貌り付けたものず同様のコヌドがあり

@noxは今日、 mergefunc llvmパスを有効にするこずを怜蚎しおいたしたが、ここで䜕か違いがあるのではないかず思いたす。

mergefuncは、耇数の同䞀の_ZN61_$LT$alloc..heap..Heap$u20$as$u20$alloc..allocator..Alloc$GT$3oom17h53c76bda5 0c6b65aE.llvm.nnnnnnnnnnnnnnn関数を削陀しないようです RUSTFLAGS -C passes=mergefuncで詊しおみたした。

しかし、倧きな違いを生むのはLTOです。これは、Firefoxがmallocを盎接呌び出すようにし、 __rust_oom呌び出す盎前にAllocErrの䜜成を任せたす。 これにより、アロケヌタを呌び出す前にLayout必芁がなくなり、 AllocErr埋めるずきにそのたたになりたす。

これにより、 __rust_oomを陀いお、割り圓お関数はおそらくむンラむンでマヌクする必芁があるず思いたす。

ずころで、Firefox甚に生成されたコヌドを芋お、 malloc代わりにmoz_xmallocを䜿甚するこずが理想的だず思いたす。 これは、アロケヌタヌ特性の組み合わせずグロヌバルヒヌプアロケヌタヌの眮き換えがなければ䞍可胜ですが、アロケヌタヌ特性のカスタム゚ラヌタむプが必芁になる可胜性がありたす。 moz_xmallocは間違いなく、次の堎合には返されたせん。倱敗。 IOW、それはOOM自䜓を凊理し、その堎合、錆びたコヌドは__rust_oomを呌び出す必芁はありたせん。 これにより、アロケヌタ関数がオプションでAllocErrではなく!返すこずが望たしいでしょう。

AllocErrをれロサむズの構造䜓にするこずに぀いお説明したした。これもここで圹立぀可胜性がありたす。 ポむンタもNonNullにするず、戻り倀党䜓をポむンタサむズにするこずができたす。

https://github.com/rust-lang/rust/pull/49669は、グロヌバルアロケヌタヌをカバヌするサブセットを安定させるこずを目的ずしお、これらのAPIに倚くの倉曎を加えおいたす。 そのサブセットの远跡の問題 https  新しいGlobalAlloc特性が導入されたした。

このPRは、私たちはのようなこずを行うこずができたすVec::new_with_alloc(alloc)ずころalloc: Allocすぐに

@alexregいいえ

@sfacklerうヌん、どうしお それを行う前に䜕が必芁ですか グロヌバルアロケヌタを倉曎するだけの堎合を陀いお、このPRのポむントは他の方法では実際にはわかりたせん。

@alexreg

グロヌバルアロケヌタを倉曎するだけの堎合を陀いお、このPRのポむントは他の方法では実際にはわかりたせん。

グロヌバルアロケヌタヌを倉曎するためだけだず思いたす。

@alexreg安定しおいるずいうこずであれば、安定させる準備ができおいない未解決の蚭蚈䞊の質問がいく぀かありたす。 Nightlyでは、これはRawVecサポヌトされおおり、それに取り組んでみたいず思う人のために、 Vec #[unstable]ずしお远加しおも問題ありたせん。

はい、PRで述べたように、そのポむントは、グロヌバルアロケヌタヌを倉曎したり、 Vec::with_capacityせずにカスタムコレクションタむプなどで割り圓おたりできるようにするこずです。

FWIW、 https //github.com/rust-lang/rust/issues/32838#issuecomment -376793369で蚀及されおいるallocator_apiクレヌトには、マスタヌにRawVec<T, A>ずBox<T, A>がありたすブランチただリリヌスされおいたせん。 私はそれを、割り圓おタむプに察しおゞェネリックなコレクションがどのように芋えるかに぀いおのむンキュベヌタヌずしお考えおいたすさらに、安定した錆のためにBox<T, A>タむプが必芁であるずいう事実。 Vec<T, A>を远加するためのvec.rsの移怍はただ開始しおいたせんが、PRは倧歓迎です。 vec.rsは倧きいです。

https://github.com/rust-lang/rust/issues/32838#issuecomment -377097485で蚀及されおいるcodegenの「問題」は、49669の倉曎で削陀されるはずです。

さお、 Allocトレむトを䜿甚しおアロケヌタヌをレむダヌに実装するのに圹立぀こずをもう少し考えおみるず、少なくずも私にずっおは圹立぀ず思うこずが2぀ありたす。

  • 前述のように、オプションで別のAllocErrタむプを指定できたす。 これは、 !にする堎合や、AllocErrが空になったため、オプションで「倱敗」よりも倚くの情報を䌝達する堎合に圹立ちたす。
  • オプションで、別のLayoutタむプを指定できたす。 アロケヌタの2぀の局があるず想像しおください。1぀はペヌゞ割り圓お甚で、もう1぀はより倧きな領域甚です。 埌者は前者に䟝存できたすが、䞡方が同じLayoutタむプをずる堎合、䞡方のレむダヌが独自の怜蚌を行う必芁がありたす。最䜎レベルでは、そのサむズず配眮はペヌゞサむズの倍数です。より高いレベルでは、そのサむズず配眮はより倧きな領域の芁件に䞀臎したす。 しかし、これらのチェックは冗長です。 特殊なLayoutタむプを䜿甚するず、怜蚌をアロケヌタヌ自䜓ではなくLayout䜜成に委任でき、 Layoutタむプ間の倉換により、冗長なチェックをスキップできたす。

@cramertj @SimonSapin @glandiumわかりたした、明確にしおいただきありがずうcrate 、

@alexregは、49669のAlloc特性に察する重倧な倉曎の量を考慮するず、最初にマヌゞされるのを埅぀方がよいでしょう。

@glandiumたあたあ。 それは着陞からそれほど遠くないようです。 https://github.com/pnkfelix/collections-primeレポにも気づきたした...あなたずの関係でそれは䜕ですか

もう1぀未解決の質問を远加したす。

  • Alloc::oomはパニックに陥るこずができたすか 珟圚、ドキュメントには、このメ゜ッドはプロセスを䞭止する必芁があるず曞かれおいたす。 これは、アロケヌタを䜿甚するコヌドに圱響を及がしたす。アロケヌタは、メモリリヌクなしでアンワむンドを適切に凊理するように蚭蚈する必芁があるためです。

ロヌカルアロケヌタヌの障害は必ずしもグロヌバルアロケヌタヌも倱敗するこずを意味するわけではないので、パニックを蚱容する必芁があるず思いたす。 最悪の堎合、グロヌバルアロケヌタのoomが呌び出され、プロセスが䞭止されたすそうしないず、既存のコヌドが砎損したす。

@alexregそうではありたせん。 std / alloc / collectionsにあるものの単玔なコピヌのようです。 さお、それの2幎前のコピヌ。 私のクレヌトは範囲がはるかに制限されおいたす公開されたバヌゞョンには数週間前の時点でAlloc特性しかなく、マスタヌブランチにはRawVecずBoxしかありたせんそれ、そしお私の目暙の1぀は、安定した錆でそれを構築し続けるこずです。

@glandiumさお、その堎合、そのPRが着陞するたで埅っおから、錆びたマスタヌに察しおPRを䜜成し、タグを付けるのはおそらく理にかなっおいたす。そうすれば、い぀マスタヌにマヌゞされるかがわかりたすそしお、クレヌトにマヌゞできたす。 、フェア

@alexregは理にかなっおいたす。 あなたは今それを始めるこずができたすが、バむクシェディングがそのPRの状況を倉える堎合、それはあなたの偎にいくらかのチャヌンを匕き起こす可胜性がありたす。

@glandium今のずころ、Rustで忙しくしおいる他のこずがありたすが、そのPRが承認されたらそれに

Alloc :: oomはパニックに陥るこずができたすか 珟圚、ドキュメントには、このメ゜ッドはプロセスを䞭止する必芁があるず曞かれおいたす。 これは、アロケヌタを䜿甚するコヌドに圱響を及がしたす。アロケヌタは、メモリリヌクなしでアンワむンドを適切に凊理するように蚭蚈する必芁があるためです。

@AmanieuこのRFCはマヌゞされたした https 

PRの提出を怜蚎しおいるAPIに1぀の倉曎がありたす。

Allocトレむトを「実装」ず「ヘルパヌ」の2぀の郚分に分割したす。 前者はalloc 、 dealloc 、 reallocなどの関数であり、埌者はalloc_one 、 dealloc_one 、 alloc_arrayような関数です。

OTOH、 Allocトレむト実装者がalloc_oneなどで凝ったこずを行おうずした堎合、その割り圓おのためにdealloc_oneが呌び出される保蚌はありたせん。 これには耇数の理由がありたす。

  • ヘルパヌは䞀貫しお䜿甚されおいたせん。 ほんの䞀䟋ずしお、 raw_vecはalloc_array 、 alloc / alloc_zeroed組み合わせを䜿甚したすが、 deallocのみを䜿甚したす。
  • たずえばalloc_array / dealloc_arrayを䞀貫しお䜿甚しおいる堎合でも、 VecをBoxに安党に倉換できたす。これによりdealloc䜿甚されたす。
  • 次に、存圚しないAPIの䞀郚がありたす alloc_one / alloc_arrayのれロ化バヌゞョンはありたせん

したがっお、たずえばalloc_one特殊化の実際のナヌスケヌスがありたすが実際には、mozjemallocが必芁です、代わりに特殊化されたアロケヌタヌを䜿甚するこずをお勧めしたす。

実際、それよりも悪いですが、錆のレポでは、 alloc_arrayがalloc_oneだけ䜿甚され、 dealloc_one 、 realloc_array 、 dealloc_arrayは䜿甚されたせん。 alloc_oneを䜿甚せず、 exchange_mallocを䜿甚したす。これには、 sizeずalignです。 したがっお、これらの関数は、実装者よりもクラむアントの利䟿性を目的ずしおいたす。

impl<A: Alloc> AllocHelpers for A たたはAllocExt 、どの名前を遞択しおものようなものを䜿甚するず、実装者が考えた堎合に自分の足を撃぀こずを蚱可せずに、クラむアントにずっおこれらの関数の䟿利さを維持できたす。それらはそれらをオヌバヌラむドするこずによっおそしおプロキシアロケヌタヌを実装する人々にずっおより簡単にするこずによっお掟手なこずをするでしょう。

PRを提出するこずを怜蚎しおいるAPIに1぀の倉曎がありたす

50436でそうしたした

@glandium

そしお実際のずころ、私はmozjemallocをそのように必芁ずしおいたす、

このナヌスケヌスに぀いお詳しく教えおください。

mozjemallocには、意図的にリヌクするベヌスアロケヌタヌがありたす。 フリヌリストを保持する1皮類のオブゞェクトを陀きたす。 alloc_oneトリックを行うのではなく、アロケヌタヌを階局化するこずでそれを行うこずができたす。

割り圓おた正確な配眮を割り圓お解陀する必芁がありたすか

この質問ぞの答えが「はい」であるこずを匷調するために、私はマむクロ゜フト自身からこの玠敵な匕甚を持っおい

Alined_allocは、C11が実装ず互換性のない方法で指定したため、おそらく実装されたせん぀たり、freeは高床に調敎された割り圓おを凊理できる必芁がありたす

Windowsでシステムアロケヌタを䜿甚するには、高床に調敎された割り圓おを正しく割り圓お解陀するために、割り圓おを解陀するずきに垞に配眮を知っお

Windowsでシステムアロケヌタを䜿甚するには、高床に調敎された割り圓おを正しく割り圓お解陀するために、割り圓おを解陀するずきに垞に配眮を知っお

それは残念ですが、それはそうです。 それでは、オヌバヌアラむンされたベクトルをあきらめたしょう。 混乱

オヌバヌアラむンされたベクトルをあきらめたしょう

どうしお オヌバヌアラむンメントで割り圓おず割り圓お解陀の䞡方を行うVec<T, OverAlignedAlloc<U16>>が必芁です。

どうしお オヌバヌアラむンメントで割り圓おず割り圓お解陀の䞡方を行うVec<T, OverAlignedAlloc<U16>>が必芁です。

もっず具䜓的にすべきだった。 ぀たり、オヌバヌアラむンされたベクタヌを、コントロヌル倖のAPIに移動するこずを意味したした。぀たり、 Vec<T, OverAlignedAlloc<U16>>ではなくVec<T>を䜿甚するAPIです。 たずえば、 CString::new() 。

あなたはむしろ䜿甚する必芁がありたす

#[repr(align(16))]
struct OverAligned16<T>(T);

次にVec<OverAligned16<T>> 。

あなたはむしろ䜿甚する必芁がありたす

堎合によりたす。 f32 sのベクトルでAVX組み蟌み関数256ビット幅、32バむトのアラむメント芁件を䜿甚するずしたす。

  • Vec<T, OverAlignedAlloc<U32>>は問題を解決し、AVX組み蟌み関数をベクトル芁玠特に敎列されたメモリロヌドで盎接䜿甚できたすが、ベクトルは䟝然ずしお&[f32]スラむスにデレフされ、人間工孊的に䜿甚できたす。
  • Vec<OverAligned32<f32>>は実際には問題を解決したせん。 各f32は、配眮芁件のために32バむトのスペヌスを必芁ずしたす。 導入されたパディングは、 f32が連続メモリ䞊にないため、AVX操䜜を盎接䜿甚できないようにしたす。 そしお、私は個人的に&[OverAligned32<f32>]ぞのderefを扱うのが少し面倒だず思いたす。

Box 、 Box<T, OverAligned<U32>>察Box<OverAligned32<T>>単䞀芁玠の堎合、䞡方のアプロヌチはより同等であり、2番目のアプロヌチが実際に望たしい堎合がありたす。 いずれにせよ、䞡方のオプションがあるず䟿利です。

Alloc特性ぞのこのwrt倉曎を投皿したした https 

この号の冒頭にある远跡投皿はひどく叀くなっおいたす最埌に線集されたのは2016幎です。 議論を生産的に続けるには、掻発な懞念事項の最新リストが必芁です。

議論はたた、珟圚の未解決の質問ず蚭蚈決定の論理的根拠を含む最新の蚭蚈文曞から倧きな恩恵を受けるでしょう。

「珟圚毎晩実装されおいるもの」から「元のAllocRFCで提案されたもの」たで、さたざたなチャネルrfcリポゞトリ、rust-langトラッキングの問題、グロヌバルalloc RFC、内郚投皿、倚くに数千のコメントを生成するdiffのスレッドが耇数ありたす。巚倧なPRなど、そしおGlobalAlloc RFCで安定しおいるものは、元のRFCで提案されたものずあたり䌌おいたせん。

これは、ドキュメントずリファレンスの曎新を完了するためにずにかく必芁なものであり、珟圚のディスカッションでも圹立ちたす。

Alloc特性の安定化に぀いお考える前に、たずすべおの暙準ラむブラリコレクションにアロケヌタサポヌトを実装しおみる必芁があるず思いたす。 これにより、この特性が実際にどのように䜿甚されるかに぀いおの経隓が埗られるはずです。

Alloc特性の安定化に぀いお考える前に、たずすべおの暙準ラむブラリコレクションにアロケヌタサポヌトを実装しおみる必芁があるず思いたす。 これにより、この特性が実際にどのように䜿甚されるかに぀いおの経隓が埗られるはずです。

そのずおり。 特にBox 、 Box<T, A>に2぀の単語を䜿甚させないようにする方法がただわからないためです。

そのずおり。 特にBox、Boxを避ける方法がただわからないので2぀の蚀葉を取り䞊げたす。

最初の実装ではBox<T, A>のサむズを心配する必芁はないず思いたすが、これは、サポヌトするだけのDeAllocトレむトを远加するこずで、䞋䜍互換性のある方法で埌で远加できるものです。割り圓お解陀。

䟋

trait DeAlloc {
    fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout);
}

trait Alloc {
    // In addition to the existing trait items
    type DeAlloc: DeAlloc = Self;
    fn into_dealloc(self) -> Self::DeAlloc {
        self
    }
}

impl<T: Alloc> DeAlloc for T {
    fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
        Alloc::dealloc(self, ptr, layout);
    }
}

Allocトレむトの安定化に぀いお考える前に、たずすべおの暙準ラむブラリコレクションにアロケヌタヌサポヌトを実装しおみる必芁があるず思いたす。 これにより、この特性が実際にどのように䜿甚されるかに぀いおの経隓が埗られるはずです。

https://github.com/rust-lang/rust/issues/42774によるず、 @ Ericson2314がこれに取り組んでいるず思いたす。 圌から最新情報を入手できたら嬉しいです。

最初の実装ではBox<T, A>のサむズを心配する必芁はないず思いたすが、これは、サポヌトするだけのDeAllocトレむトを远加するこずで、䞋䜍互換性のある方法で埌で远加できるものです。割り圓お解陀。

それは1぀のアプロヌチですが、それが間違いなく最良のアプロヌチであるかどうかは私にはたったくわかりたせん。 これには明確な欠点がありたす。たずえば、aポむンタ->アロケヌタルックアップが可胜な堎合にのみ機胜しこれは、ほずんどのアリヌナアロケヌタには圓おはたりたせん、b deallocかなりのオヌバヌヘッドが远加されたす。 この提案たたはこの提案のような、より汎甚的な効果たたはコンテキストシステムである堎合がありたす。 あるいは、たったく別の䜕かかもしれたせん。 したがっお、これがAlloc特性の珟圚の化身ず䞋䜍互換性のある方法で簡単に解決できるず想定するべきではないず思いたす。

@joshlf Box<T, A>はドロップされたずきにのみ自分自身にアクセスできるずいう事実を考えるず、これは安党なコヌドのみで実行できる最善のこずです。 このようなパタヌンは、操䜜なしのdeallocあり、アロケヌタヌがドロップされたずきにメモリを解攟するだけのアリヌナのようなアロケヌタヌに圹立぀堎合がありたす。

アロケヌタがコンテナ LinkedList によっお所有され、耇数の割り圓おを管理する、より耇雑なシステムの堎合、 Boxは内郚で䜿甚されないず予想されたす。 代わりに、 LinkedList内郚は、 LinkedListオブゞェクトに含たれおいるAllocむンスタンスで割り圓おられお解攟される生のポむンタヌを䜿甚したす。 これにより、すべおのポむンタヌのサむズが2倍になるのを防ぐこずができたす。

Box<T, A>はドロップされたずきにのみ自分自身にアクセスできるずいう事実を考えるず、これは安党なコヌドのみで実行できる最善のこずです。 このようなパタヌンは、操䜜なしのdeallocあり、アロケヌタヌがドロップされたずきにメモリを解攟するだけのアリヌナのようなアロケヌタヌに圹立぀堎合がありたす。

そうですが、 Boxは、 deallocがノヌオペレヌションであるこずを知りたせん。

アロケヌタヌがコンテナヌによっお所有され LinkedList 、耇数の割り圓おを管理する、より耇雑なシステムの堎合、Boxは内郚で䜿甚されないこずを期埅しおいたす。 代わりに、 LinkedList内郚は、 LinkedListオブゞェクトに含たれおいるAllocむンスタンスで割り圓おられお解攟される生のポむンタヌを䜿甚したす。 これにより、すべおのポむンタヌのサむズが2倍になるのを防ぐこずができたす。

コレクションを䜜成するために安党でないコヌドを䜿甚するように人々に芁求するこずは本圓に残念だず思いたす。 目暙がすべおのコレクションおそらく暙準ラむブラリの倖郚のものを含むをアロケヌタヌでオプションでパラメトリックにするこずであり、 Boxがアロケヌタヌパラメトリックではない堎合、コレクションの䜜成者はBox䜿甚しおはなりたせん。

そうですが、Boxはdeallocがノヌオペレヌションであるこずを知りたせん。

なぜC ++ unique_ptrが行うこずを適応させないのですか
぀たり、アロケヌタが「ステヌトフル」の堎合はポむンタを栌玍し、アロケヌタが「ステヌトレス」の堎合は栌玍しないようにしたす。
たずえば、 mallocたたはmmapグロヌバルラッパヌ。
これには、珟圚のAllocトレむンをStatefulAllocずStatelessAlloc 2぀の特性に分割する必芁がありたす。
私はそれが非垞に倱瀌で゚レガントでないこずを理解しおいたすそしおおそらく誰かが以前の議論でそれをすでに提案したした。
その優雅さにもかかわらず、この゜リュヌションはシンプルで䞋䜍互換性がありたすパフォヌマンスのペナルティはありたせん。

コレクションを䜜成するために安党でないコヌドを䜿甚するように人々に芁求するこずは本圓に残念だず思いたす。 目暙がすべおのコレクションおそらく暙準ラむブラリの倖郚のものを含むをアロケヌタヌでオプションでパラメトリックにするこずであり、Boxがアロケヌタヌパラメトリックではない堎合、コレクションの䜜成者はBoxをたったく䜿甚しないか、安党でないコヌドを䜿甚する必芁がありたすおよび垞に物事を解攟するこずを芚えおおくこずは、CおよびC ++で最も䞀般的なタむプのメモリの安党性の問題の1぀であるため、安党でないコヌドを正しく取埗するのは困難です。 それは䞍幞な掘り出し物のようです。

リストやツリヌなどのノヌドベヌスのコンテナを安党な方法で蚘述できる゚フェクトたたはコンテキストシステムの実装には、時間がかかりすぎる可胜性がありたす原則ずしお可胜であれば。
この問題に取り組んでいる論文や孊術蚀語は芋圓たりたせんでしたそのような䜜品が実際に存圚する堎合は蚂正しおください。

したがっお、ノヌドベヌスのコンテナの実装でunsafeに頌るこずは、少なくずも短期的には必芁悪かもしれたせん。

@eucpp泚unique_ptr保存されおいないがallocator--それが栌玍Deleter 

Deleterは、FunctionObjectたたはFunctionObjectぞの巊蟺倀参照、たたは関数ぞの巊蟺倀参照である必芁があり、unique_ptr型の匕数で呌び出すこずができたす。::ポむンタ `

これは、分割されたAllocずDealloc特性を提䟛するこずずほが同等であるず思いたす。

@cramertjはい、その通りです。 それでも、ステヌトフルずステヌトレスの2぀の特性が必芁ですDealloc 。

ZST Deallocで十分ではないでしょうか

15:08 Evgeniy Moiseenkoで火、2018幎6月12日には[email protected]
曞きたした

@cramertj https://github.com/cramertjはい、その通りです。 それでも、2぀
特性が必芁です-ステヌトフルおよびステヌトレスDealloc。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/rust-lang/rust/issues/32838#issuecomment-396716689 、
たたはスレッドをミュヌトしたす
https://github.com/notifications/unsubscribe-auth/AEAJtWkpF0ofVc18NwbfV45G4QY6SCFBks5t8B_AgaJpZM4IDYUN
。

ZST Deallocで十分ではないでしょうか

@remexre私はそれがそうなるず思いたす:)

rustコンパむラがZSTをすぐにサポヌトするこずを知りたせんでした。
C ++では、空のベヌスの最適化に関する少なくずもいく぀かのトリックが必芁になりたす。
私はRustでかなり新しいので、いく぀かの明らかな間違いをお詫びしたす。

ステヌトフルずステヌトレスに別々の特性が必芁だずは思いたせん。

Box A型パラメヌタヌを远加するず、 Aぞの参照やポむンタヌではなく、 A倀が盎接含たれたす。 そのタむプは、ステヌトレスデアロケヌタのサむズをれロにするこずができたす。 たたは、 A自䜓は、割り圓おられた耇数のオブゞェクト間で共有できるステヌトフルアロケヌタヌぞの参照たたはハンドルのようなものにするこずができたす。 したがっお、 impl Alloc for MyAllocator代わりに、 impl<'r> Alloc for &'r MyAllocatorようなこずをしたいず思うかもしれたせん。

ちなみに、割り圓お解陀の方法だけを知っおいお、割り圓お方法を知らないBox 、 Clone実装したせん。

@SimonSapin Clone ingでは、新しいBoxを䜜成するのず同じ方法で、アロケヌタヌを再床指定する必芁があるず思いたす぀たり、 Cloneを䜿甚しお実行するこずはありたせん。

@cramertj VecやCloneを実装する他のコンテナず比范しお䞀貫性がないのではないでしょうか。
むンスタンス栌玍する欠点は䜕ですかAlloc内偎BoxではなくDealloc 
次に、 BoxはCloneずclone_with_alloc実装する可胜性がありたす。

私はこれを分割特性が実際にクロヌンに倧きな圱響を䞎えるずは思いたせん-implはimpl<T, A> Clone for Box<T, A> where A: Alloc + Dealloc + Clone { ... }たす。

@sfackler私はそのimplに反察したせんが、 clone_intoたたは提䟛されたアロケヌタヌを䜿甚するものがあるこずも期埅したす。

alloc_copyメ゜ッドからAlloc意味がありたすか これは、たずえばペヌゞのコピヌオンラむトクロヌンを䜜成するこずにより、倧芏暡な割り圓おに察しおより高速なmemcpy Copy/Clone 実装を提䟛するために䜿甚できたす。

これはかなりクヌルで、デフォルトの実装を提䟛するのは簡単です。

このようなalloc_copy関数を䜿甚するずどうなるでしょうか。 impl Clone for Box<T, A> 

ええ、 Vec同䞊。

もう少し調べおみるず、少なくずも1レベル以䞊の深さで䜜成したい堎合は、ハッキヌず䞍可胜の間の同じプロセス範囲内でコピヌオンラむトペヌゞを䜜成するアプロヌチのようです。 したがっお、 alloc_copyは倧きなメリットにはなりたせん。

代わりに、将来の仮想メモリのシェナニガンを可胜にする、より䞀般的な゚スケヌプハッチが圹立぀可胜性がありたす。 ぀たり、割り圓おが倧きく、ずにかくmmapに支えられおステヌトレスである堎合、アロケヌタは割り圓おの将来の倉曎に぀いお気付かないこずを玄束できたす。 次に、ナヌザヌはそのメモリをパむプに移動したり、マップを解陀したりするこずができたす。
あるいは、ダムのmmap-all-the-thingsアロケヌタヌずtry-transfer関数が存圚する可胜性がありたす。

代わりに、将来の仮想メモリを可胜にするより䞀般的な゚スケヌプハッチ

メモリアロケヌタmalloc、jemalloc、...は、通垞、それらから任意の皮類のメモリを盗むこずはできたせん。たた、通垞、所有するメモリのプロパティを照䌚たたは倉曎するこずもできたせん。 では、この䞀般的な゚スケヌプハッチはメモリアロケヌタず䜕の関係があるのでしょうか。

たた、仮想メモリのサポヌトはプラットフォヌム間で倧きく異なるため、仮想メモリを効果的に䜿甚するには、プラットフォヌムごずに異なるアルゎリズムが必芁になるこずが倚く、保蚌もたったく異なりたす。 私は仮想メモリ䞊でいく぀かの移怍可胜な抜象化を芋おきたしたが、それらの「移怍性」のためにいく぀かの状況で圹に立たないほど機胜しなくなっおいないものはただ芋おいたせん。

あなたが正しい。 そのようなナヌスケヌス私は䞻にプラットフォヌム固有の最適化を考えおいたしたは、おそらく最初にカスタムアロケヌタヌを䜿甚するこずによっお最もよく提䟛されたす。

AndreiAlexandrescuがCppConプレれンテヌションで説明したComposableAllocator APIに぀いお䜕か考えはありたすか ビデオはここのYouTubeで利甚可胜です https  たす、しかし話はあなたがそれを通しお芋るこずを奜むかもしれない十分に面癜いです 。

これらすべおの必然的な結論は、コレクションラむブラリは䞀般的なWRT割り圓おであり、アプリプログラマヌ自身が建蚭珟堎でアロケヌタヌずコレクションを自由に䜜成できる必芁があるずいうこずのように思えたす。

AndreiAlexandrescuがCppConプレれンテヌションで説明したComposableAllocator APIに぀いお䜕か考えはありたすか

珟圚のAlloc APIを䜿甚するず、構成可胜なアロケヌタヌ MyAlloc<Other: Alloc> を蚘述でき、特性ず特殊化を䜿甚しお、Andreisトヌクで達成されるほずんどすべおを達成できたす。 ただし、AndreiがAPIを構築する方法は、最初から制玄のないゞェネリック+ SFINAE / staticに基づいおいるため、Andreiの話からはほずんど䜕もRustに適甚できないずいう「アむデア」を超えお、Rustのゞェネリックシステムそれずは党然違いたす。

残りのLayoutメ゜ッドを安定させるこずを提案したいず思いたす。 これらは、珟圚のグロヌバルアロケヌタAPIですでに圹立ちたす。

これらはあなたが意味するすべおの方法ですか

  • pub fn align_to(&self, align: usize) -> Layout
  • pub fn padding_needed_for(&self, align: usize) -> usize
  • pub fn repeat(&self, n: usize) -> Result<(Layout, usize), LayoutErr>
  • pub fn extend(&self, next: Layout) -> Result<(Layout, usize), LayoutErr>
  • pub fn repeat_packed(&self, n: usize) -> Result<Layout, LayoutErr>
  • pub fn extend_packed(&self, next: Layout) -> Result<(Layout, usize), LayoutErr>
  • pub fn array<T>(n: usize) -> Result<Layout, LayoutErr>

@gnzlbgはい。

@Amanieuは私には問題ないように

アロケヌタヌずラむフタむムから

  1. allocator implsの堎合allocator倀を移動しおも、未凊理のメモリブロックが無効になっおはなりたせん。

    すべおのクラむアントは、コヌドでこれを想定できたす。

    したがっお、クラむアントがアロケヌタからブロックを割り圓おa1ず呌びたす、次にa1が新しい堎所に移動した堎合たずえば、vialet a2 = a1;、クラむアントがa2を介しおそのブロックの割り圓おを解陀するこずは健党なたたです。

これは、アロケヌタがUnpinなければならないこずを意味したすか

いいキャッチ

Allocトレむトはただ䞍安定なので、RFCのこの郚分を倉曎したい堎合は、ルヌルを倉曎できるず思いたす。 しかし、それは確かに心に留めおおくべきこずです。

@gnzlbgはい、ゞェネリックシステムの倧きな違いを認識しおいたす。圌が詳述するすべおがRustで同じように実装できるわけではありたせん。 ずはいえ、投皿以来、ラむブラリのオンずオフに取り組んでおり、順調に進んでいたす。

これは、アロケヌタがUnpinなければならないこずを意味したすか

そうではありたせん。 Unpinは、 Pinでラップされたずきの型の動䜜に関するものであり、このAPIぞの特別な接続はありたせん。

しかし、 Unpinを䜿甚しお前述の制玄を適甚するこずはできたせんか

dealloc_arrayに関する別の質問関数がResult返すのはなぜですか 珟圚の実装では、これは2぀の堎合に倱敗する可胜性がありたす。

  • nはれロです
  • n * size_of::<T>()容量オヌバヌフロヌ

最初のケヌスには2぀のケヌスがありたすドキュメントのように、実装者はこれらから遞択できたす。

  • 割り圓おを返しOkれロ化にn => dealloc_arrayも返す必芁がOk 。
  • 割り圓おは、れロ化されたn =>にErrを返したす。 dealloc_array枡すこずができるポむンタはありたせん。

2぀目は、次の安党䞊の制玄によっお保蚌されたす。

[T; n]のレむアりトは、そのメモリブロックに適合しおいる必芁

぀たり、割り圓おず同じn dealloc_arrayを呌び出す必芁がありたす。 n芁玠を持぀配列を割り圓おるこずができる堎合、 nはTに察しお有効です。 そうでなければ、割り圓おは倱敗するでしょう。

線集最埌の点に぀いお usable_sizeがn * size_of::<T>()よりも高い倀を返したずしおも、これは匕き続き有効です。 それ以倖の堎合、実装はこの特性制玄に違反したす。

ブロックのサむズは[use_min, use_max]範囲内にある必芁がありたす。ここで、

  • [...]
  • use_maxは、ブロックがalloc_excessたたはrealloc_excessぞの呌び出しを介しお割り圓おられたずきに返されたたたは返されたはずの容量です。

特性にはunsafe implが必芁なため、これは圓おはたりたす。

最初のケヌスには2぀のケヌスがありたすドキュメントのように、実装者はこれらから遞択できたす。

  • 割り圓おは、れロ化されたn Okを返したす

この情報はどこから入手したしたか

ドキュメント内のすべおのAlloc::alloc_メ゜ッドは、れロサむズの割り圓おの動䜜が「Safety」句で定矩されおいないこずを指定しおいたす。

core::alloc::Allocドキュメント匷調衚瀺された関連郚分

れロサむズの型ずれロサむズのレむアりトに関する泚意 Allocトレむトの倚くのメ゜ッドは、割り圓お芁求はれロ以倖のサむズでなければならないず述べおいたす。そうしないず、未定矩の動䜜が発生する可胜性がありたす。

  • ただし、䞀郚の高レベルの割り圓お方法 alloc_one 、 alloc_array は、サむズがれロの型で明確に定矩されおおり、オプションでそれらをサポヌトできたす。 ErrをErr 、たたはポむンタを付けお
  • この堎合、 Alloc実装がOkを返すこずを遞択した堎合぀たり、ポむンタヌがれロサむズのアクセスできないブロックを瀺しおいる堎合、返されたポむンタヌは「珟圚割り圓おられおいる」ず芋なす必芁がありたす。 このようなアロケヌタでは、珟圚割り圓おられおいるポむンタを入力ずしお受け取るすべおのメ゜ッドは、未定矩の動䜜を匕き起こす

  • 蚀い換えるず、れロサむズのポむンタヌがアロケヌタヌから流出する可胜性がある堎合、そのアロケヌタヌは同様に、そのポむンタヌが割り圓お解陀および再割り圓おメ゜ッドに逆流するこずを受け入れる必芁がありたす。

したがっお、 dealloc_arrayの゚ラヌ状態の1぀は間違いなく疑わしいものです。

/// # Safety
///
/// * the layout of `[T; n]` must *fit* that block of memory.
///
/// # Errors
///
/// Returning `Err` indicates that either `[T; n]` or the given
/// memory block does not meet allocator's size or alignment
/// constraints.

[T; N]がアロケヌタのサむズたたは配眮の制玄を満たさない堎合、AFAICTは割り圓おのメモリブロックに適合せず、動䜜は未定矩です安党条項による。

もう1぀の゚ラヌ条件は、「算術オヌバヌフロヌ時に垞にErrを返す」です。 これはかなり䞀般的です。 それが有甚な゚ラヌ状態であるかどうかを芋分けるのは難しいです。 Alloc特性の実装ごずに、理論的にラップできる算術挔算を実行できる別の実装を思い付くこずができる可胜性があるため、🀷‍♂


core::alloc::Allocドキュメント匷調衚瀺された関連郚分

確かに。 非垞に倚くのメ゜ッド Alloc::alloc がれロサむズの割り圓おが未定矩の動䜜であるず述べおいるのは奇劙だず思いたすが、 Alloc::alloc_array(0)に実装定矩の動䜜を提䟛するだけです。 ある意味で、 Alloc::alloc_array(0)は、アロケヌタヌがれロサむズの割り圓おをサポヌトしおいるかどうかを確認するためのリトマス詊隓です。

[T; N]がアロケヌタのサむズたたは配眮の制玄を満たさない堎合、AFAICTは割り圓おのメモリブロックに適合せず、動䜜は未定矩です安党条項による。

うん、この゚ラヌ状態は冗長なので削陀できるず思いたす。 安党条項たたぱラヌ条件のいずれかが必芁ですが、䞡方は必芁ありたせん。

もう1぀の゚ラヌ条件は、「算術オヌバヌフロヌ時に垞にErrを返す」です。 これはかなり䞀般的です。 それが有甚な゚ラヌ状態であるかどうかを芋分けるのは難しいです。

IMO、それは䞊蚘ず同じ安党条項によっお守られおいたす。 [T; N]の容量がオヌバヌフロヌした堎合、そのメモリブロックは割り圓お解陀に適合したせん。 たぶん@pnkfelixはこれに぀いお詳しく

ある意味で、 Alloc::alloc_array(1)は、アロケヌタヌがれロサむズの割り圓おをサポヌトしおいるかどうかを確認するためのリトマス詊隓です。

Alloc::alloc_array(0)ですか

IMO、それは䞊蚘ず同じ安党条項によっお守られおいたす。 [T; N]の容量がオヌバヌフロヌした堎合、そのメモリブロックの割り圓おを解陀するこずはできたせん。

この特性は、ナヌザヌが独自のカスタムアロケヌタヌに察しお実装できるこず、およびこれらのナヌザヌがこれらのメ゜ッドのデフォルトの実装をオヌバヌラむドできるこずに泚意しおください。 したがっお、これが算術オヌバヌフロヌに察しおErrを返すかどうかを怜蚎するずきは、デフォルトメ゜ッドの珟圚のデフォルト実装が䜕をするかに焊点を圓おるだけでなく、他の人のためにこれらを実装するナヌザヌにずっお䜕が理にかなっおいるかも考慮する必芁がありたす。アロケヌタヌ。

Alloc::alloc_array(0)ですか

うん、ごめん。

この特性は、ナヌザヌが独自のカスタムアロケヌタヌに察しお実装できるこず、およびこれらのナヌザヌがこれらのメ゜ッドのデフォルトの実装をオヌバヌラむドできるこずに泚意しおください。 したがっお、これが算術オヌバヌフロヌに察しおErrを返すかどうかを怜蚎するずきは、デフォルトメ゜ッドの珟圚のデフォルト実装が䜕をするかに焊点を圓おるだけでなく、他の人のためにこれらを実装するナヌザヌにずっお䜕が理にかなっおいるかも考慮する必芁がありたす。アロケヌタヌ。

わかりたしたが、 Alloc実装するにはunsafe implが必芁であり、実装者はhttps://github.com/rust-lang/rust/issues/32838#issuecomment-467093527に蚘茉されおいる安党芏則に埓う必芁があり

远跡の問題のためにここに残されたすべおのAPIは、 Alloc特性であるか、 Alloc特性に関連しおいたす。 @ rust-lang / libs、 https//github.com/rust-lang/rust/issues/42774に加えお、これを開いたたたにしおおくず䟿利だず思い

簡単な背景の質問ZSTの柔軟性の背埌にある動機は䜕ですか コンパむル時に型がZSTであるこずがわかっおいるので、割り圓お定数倀を返すためず割り圓お解陀の䞡方を完党に最適化できるように思われたす。 それを考えるず、私たちは次のいずれかを蚀うべきだず私には思えたす

  • ZSTをサポヌトするかどうかは垞に実装者次第であり、ZSTに察しおErrを返すこずはできたせん。
  • ZSTを割り圓おるのは垞にUBであり、この堎合に短絡するのは呌び出し元の責任です。
  • 呌び出し元が実装するある皮のalloc_innerメ゜ッドず、短絡を行うデフォルトの実装を持぀allocメ゜ッドがありたす。 allocはZSTをサポヌトする必芁がありたすが、 alloc_innerはZSTに察しお呌び出されない堎合がありたすこれは、短絡ロゞックを1か所特性定矩内に順番に远加できるようにするためです。実装者に定型文を保存するため

珟圚のAPIの柔軟性が必芁な理由はありたすか

珟圚のAPIの柔軟性が必芁な理由はありたすか

これはトレヌドオフです。 間違いなく、Allocトレむトは実装されるよりも頻繁に䜿甚されるため、ZSTの組み蟌みサポヌトを提䟛するこずで、Allocをできるだけ簡単に䜿甚できるようにするこずが理にかなっおいる堎合がありたす。

これは、Allocトレむトの実装者がこれを凊理する必芁があるこずを意味したすが、Allocトレむトを進化させようずする人は、APIが倉曎されるたびにZSTを念頭に眮く必芁があるこずを私にずっおより重芁です。 たた、ZSTがどのように凊理されるかたたは「実装定矩」の堎合はそうなる可胜性があるを説明するこずにより、APIのドキュメントを耇雑にしたす。

C ++アロケヌタヌはこのアプロヌチを远求し、アロケヌタヌは倚くの異なる問題を解決しようずしたす。 これにより、実装や進化が困難になっただけでなく、これらすべおの問題がAPIでどのように盞互䜜甚するかにより、ナヌザヌが実際に䜿甚するこずも困難になりたした。

ZSTの凊理ずrawメモリの割り圓お/割り圓お解陀は、2぀の盎亀する異なる問題であるず思いたす。したがっお、ZSTを凊理しないだけで、AllocトレむトAPIを単玔に保぀必芁がありたす。

libstdのようなAllocのナヌザヌは、たずえば各コレクションでZSTを凊理する必芁がありたす。 それは間違いなく解決する䟡倀のある問題ですが、Allocの特性がそのための堎所ではないず思いたす。 この問題を解決するナヌティリティが必芁に応じおlibstd内に飛び出すこずを期埅したす。その堎合、そのようなナヌティリティをRFCしお、std :: heapで公開するこずができたす。

それはすべお合理的に聞こえたす。

ZSTの凊理ずrawメモリの割り圓お/割り圓お解陀は、2぀の盎亀する異なる問題であるず思いたす。したがっお、ZSTを凊理しないだけで、AllocトレむトAPIを単玔に保぀必芁がありたす。

これは、APIが実装定矩ではなく、明瀺的にZSTを凊理しないようにする必芁があるこずを意味したせんか IMO、「サポヌトされおいない」゚ラヌは、実行時にあたり圹に立ちたせん。これは、呌び出し元の倧倚数がフォヌルバックパスを定矩できないため、ZSTがサポヌトされおいないず想定する必芁があるためです。 APIを単玔化し、サポヌトされおいないこずを宣蚀する方がクリヌンなようです。

allocナヌザヌがZSTを凊理するために特殊化を䜿甚したすか それずもif size_of::<T>() == 0チェックだけですか

allocナヌザヌがZSTを凊理するために特殊化を䜿甚したすか それずもif size_of::<T>() == 0チェックだけですか

埌者で十分です。 適切なコヌドパスは、コンパむル時に簡単に削陀されたす。

これは、APIが実装定矩ではなく、明瀺的にZSTを凊理しないようにする必芁があるこずを意味したせんか

私にずっお重芁な制玄は、れロサむズの割り圓おを犁止する堎合、 Allocメ゜ッドは、枡されるLayoutがれロサむズではないず想定できる必芁があるずいうこずです。

これを実珟する方法は耇数ありたす。 1぀は、すべおのAllocメ゜ッドに別のSafety句を远加しお、 Layoutサむズがれロの堎合の動䜜が未定矩であるこずを瀺すこずです。

たたは、れロサむズのLayout犁止するこずもできたす。そうするず、 Allocはれロサむズの割り圓おに぀いお䜕も蚀う必芁がなくなりたす。これは安党に実行できないためですが、これを行うずいく぀かの欠点がありたす。

たずえば、 HashMapような䞀郚のタむプLayout 、耇数のLayoutからLayoutを構築し、最埌のLayoutはれロサむズではない堎合がありたすが、䞭間のものはそうかもしれたせん䟋えばHashSet 。 したがっお、これらのタむプは、最終的なLayoutを構築するために「䜕か他のもの」たずえば、 LayoutBuilderタむプを䜿甚し、「れロ以倖のサむズ」の小切手に支払う必芁がありたすたたはLayoutに倉換するずきの_unchecked メ゜ッド。

特殊化は、ZSTを凊理するためにallocナヌザヌによっお䜿甚されたすか たたは、size_of ::の堎合== 0チェック

ただZSTに特化するこずはできたせん。 珟圚、すべおのコヌドはsize_of::<T>() == 0たす。

これを実珟する方法は耇数ありたす。 1぀は、すべおのAllocメ゜ッドに別のSafety句を远加しお、 Layoutサむズがれロの堎合の動䜜が未定矩であるこずを瀺すこずです。

これをコンパむル時の保蚌にする方法があるかどうかを怜蚎するのは興味深いこずですが、レむアりトがれロ以倖のサむズであるずいうdebug_assertでさえ、99のバグをキャッチするのに十分なはずです。

アロケヌタヌに぀いおの議論には泚意を払っおいないので、申し蚳ありたせん。 しかし、私は長い間、アロケヌタヌが割り圓おおいる倀のタむプにアクセスできるこずを望んでいたした。 それを䜿甚できるアロケヌタ蚭蚈があるかもしれたせん。

次に、おそらくC ++ず同じ問題が発生したす。これはアロケヌタヌAPIです。

しかし、私は長い間、アロケヌタヌが割り圓おおいる倀のタむプにアクセスできるこずを望んでいたした。 T

これは䜕のために必芁ですか

@gnzblg @brson今日、割り圓おられおいる倀のタむプに぀いお_䜕か_を知るための朜圚的なナヌスケヌスがありたした。

私は、3぀の基瀎ずなるアロケヌタヌスレッドロヌカルアロケヌタヌ、ロック付きグロヌバルアロケヌタヌ、およびコルヌチンが䜿甚するアロケヌタヌの間で切り替えるこずができるグロヌバルアロケヌタヌに取り組んでいたす-ネットワヌク接続を衚すコルヌチンを最倧に制限できるずいう考え動的メモリ䜿甚量コレクション内のアロケヌタヌを制埡できない堎合、特にサヌドパヌティコヌド内*。

スレッド間を移動する可胜性のある倀Arcなどず移動しない倀を割り圓おおいるかどうかを知るず䟿利な堎合がありたす。 たたはそうではないかもしれたせん。 しかし、それは可胜なシナリオです。 珟時点では、グロヌバルアロケヌタヌには、ナヌザヌがどのアロケヌタヌから割り圓おを行うかを指瀺するために䜿甚するスむッチがありたすreallocたたはfreeには必芁ありたせん。そのためのメモリアドレスを確認できたす。

* [たた、可胜な限りロックなしでNUMAロヌカルメモリを䜿甚でき、1コア1スレッドモデルでは、合蚈メモリ䜿甚量を制限できたす]。

@raphaelcohn

私はグロヌバルアロケヌタヌに取り組んでいたす

これはGlobalAllocトレむトには圓おはたらないたたは圓おはたるずは思いたせん。 Allocトレむトには、型情報を利甚できる汎甚メ゜ッドがすでにありたす䟋 alloc_array<T>(1)は単䞀のT alloc_array<T>(1)割り圓おたす。ここで、 Tは実際の型であるため、アロケヌタヌは割り圓おの実行時に型を考慮に入れるこずができたす。 この議論の目的には、型情報を利甚するアロケヌタヌを実装するコヌドを実際に芋る方が䟿利だず思いたす。 これらのメ゜ッドが、アロケヌタヌAPIたたは他のアロケヌタヌ特性の䞀郚であるだけでなく、䞀般的なアロケヌタヌ特性の䞀郚である必芁がある理由に぀いお、良い議論を聞いたこずがありたせん。

Allocによっおパラメヌタヌ化されたタむプのどれを、タむプ情報を䜿甚するアロケヌタヌず組み合わせる぀もりであり、その結果ずしお䜕を期埅するかを知るこずも非垞に興味深いず思いたす。

AFAICTは、 T盎接割り圓おるため、そのための唯䞀の興味深いタむプはBoxです。 ほずんどのすべおの他のタむプstd割り圓おるこずはありたせんTあなたのアロケヌタは䜕も知らないこずを、いく぀かの民間の内郚型を。 たずえば、 RcずArcは、 (InternalRefCounts, T) 、 List / BTreeSetなどを割り圓おたす。内郚ノヌドタむプVec割り圓おたす。 Deque / ... Tの配列を割り圓おたすが、 T自䜓は割り圓おたせん。

BoxずVec 、䞋䜍互換性のある方法でBoxAllocずArrayAlloc特性を远加し、アロケヌタヌができるAlloc包括的実装を远加できたす。これらの問題を䞀般的な方法で攻撃する必芁がある堎合は、それらの動䜜をハむゞャックするこずに特化しおください。 しかし、タむプ情報を悪甚するためにアロケヌタヌず共謀する独自のMyAllocBoxおよびMyAllocVecタむプを提䟛するこずが、実行可胜な解決策ではない理由はありたすか

珟圚、アロケヌタヌWG専甚のリポゞトリがあり、OPのリストが叀くなっおいるため、この問題を閉じお、この機胜の議論ず远跡を1か所で行うこずができたすか

良い点@TimDiekmann そのリポゞトリ内のディスカッションスレッドを優先しお、先に進んでこれを閉じたす。

これは、䞀郚の#[unstable]属性が指す远跡の問題です。 これらの機胜が安定化たたは非掚奚になるたで、閉鎖すべきではないず思いたす。 たたは、別の問題を指すように属性を倉曎するこずもできたす。

ええ、git masterで参照されおいる䞍安定な機胜には、間違いなく未解決の远跡の問題があるはずです。

同意したした。 たた、OPぞの通知ずリンクを远加したした。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡