[英]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
塊大小調整? push_back
調用deque<char>
的簡單測試,它們的占用空間(32位操作)是什么? <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 ++標准沒有定義用於修改塊大小的接口。 我很確定它不強制要求任何實現,只是兩端插入/刪除的復雜性要求。
::: <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.