簡體   English   中英

std :: deque內存使用 - Visual C ++,以及與其他人的比較

[英]std::deque memory usage - Visual C++, and comparison to others

跟進std :: deque的內存開銷對heque的影響是什么?

Visual C ++使用以下方法根據容器元素類型管理deque塊:

#define _DEQUESIZ   (sizeof (value_type) <= 1 ? 16 \
    : sizeof (value_type) <= 2 ? 8 \
    : sizeof (value_type) <= 4 ? 4 \
    : sizeof (value_type) <= 8 ? 2 \
    : 1)    /* elements per block (a power of 2) */

這導致小元件的內存占用非常大。 通過將第一行中的16更改為128,我能夠大幅減少大型deque<char>所需的占用空間。 在100m push_back(const char& mychar)調用之后,Process Explorer Private Bytes從181MB - > 113MB下降。

  • 任何人都可以證明#define的值嗎?
  • 其他編譯器如何處理deque塊大小調整?
  • 對於100m push_back調用deque<char>的簡單測試,它們的占用空間(32位操作)是什么?
  • STL是否允許在編譯時覆蓋此塊大小,而不修改<deque>代碼?

gcc有

return __size < 512 ? size_t(512 / __size) : size_t(1);

評論

/*  The '512' is
 *  tunable (and no other code needs to change), but no investigation has
 *  been done since inheriting the SGI code.
 */

Dinkumware(MS)實現希望一次增加16個字節的雙端隊列。 難道這只是一個非常古老的實現(就像有史以來的第一個嗎?),它被調整為具有極少內存(按照今天的標准)的平台,以防止過度分配和耗盡內存(就像std::vector一樣)?

我必須在我正在處理的應用程序中實現自己的隊列,因為std::queue (使用std::deque )的2.5倍內存占用是不可接受的。

似乎很少有證據表明人們已經遇到這種低效率的互聯網,這對我來說是令人驚訝的。 我認為這樣一個基本的數據結構作為一個隊列(標准庫,不能少)在野外會非常普遍,並且會在性能/時間/空間關鍵應用程序中。 但我們在這里。

要回答最后一個問題,C ++標准沒有定義用於修改塊大小的接口。 我很確定它不強制要求任何實現,只是兩端插入/刪除的復雜性要求。

STLPort的

...... 好像 用了

::: <stl/_alloc.h>
...
enum { _MAX_BYTES = 32 * sizeof(void*) };
...
::: <deque>
...
static size_t _S_buffer_size()
{
  const size_t blocksize = _MAX_BYTES;
  return (sizeof(_Tp) < blocksize ? (blocksize / sizeof(_Tp)) : 1);
}

因此,這意味着32位上的32 x 4 = 128字節塊大小,64位上的32 x 8 = 256字節塊大小。

我的想法:從大小開銷POV來看,我認為任何實現使用可變長度塊都是有意義的,但我認為這對於deque的常量隨機訪問要求是非常困難的。

至於問題

STL是否允許在編譯時覆蓋此塊大小而不修改代碼?

這里也不可能。

阿帕奇

(似乎是Rogue Wave STL版本)顯然使用:

static size_type _C_bufsize () {
    // deque only uses __rw_new_capacity to retrieve the minimum
    // allocation amount; this may be specialized to provide a
    // customized minimum amount
    typedef deque<_TypeT, _Allocator> _RWDeque;
    return _RWSTD_NEW_CAPACITY (_RWDeque, (const _RWDeque*)0, 0);
}

所以似乎有一些機制通過專業化覆蓋塊大小和...的定義如下所示:

// returns a suggested new capacity for a container needing more space
template <class _Container>
inline _RWSTD_CONTAINER_SIZE_TYPE
__rw_new_capacity (_RWSTD_CONTAINER_SIZE_TYPE __size, const _Container*)
{
    typedef _RWSTD_CONTAINER_SIZE_TYPE _RWSizeT;

    const _RWSizeT __ratio = _RWSizeT (  (_RWSTD_NEW_CAPACITY_RATIO << 10)
                                       / _RWSTD_RATIO_DIVIDER);

    const _RWSizeT __cap =   (__size >> 10) * __ratio
                           + (((__size & 0x3ff) * __ratio) >> 10);

    return (__size += _RWSTD_MINIMUM_NEW_CAPACITY) > __cap ? __size : __cap;
}

所以我會說,這很復雜。

(如果有人想要進一步解決這個問題,請隨時直接編輯我的答案或只是發表評論。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM