How to use Microsoft C ++ distributors

I see at http://msdn.microsoft.com/en-us/library/ee292117.aspx and http://msdn.microsoft.com/en-us/library/ee292134.aspx that Microsoft provides macros and classes for specialized allocators, but I'm not sure what each of the caching strategies is, how to use them. Can someone explain when to use each of these parts?

  • Cache Templates
    • cache_freelist - The cache_freelist template cache_freelist maintains a free list of memory blocks of size Sz . When a free list is full, it uses operator delete to free memory blocks. When a free list is empty, it uses operator new to allocate new blocks of memory. The maximum size of a free list is determined by the max class passed in the Max parameter. Each memory block contains Sz bytes of useful memory and data that is required by operator new and operator delete .
    • cache_suballoc - the cache_suballoc template cache_suballoc stores freed memory blocks in a free list with unlimited length using freelist<sizeof(Type), max_unbounded> , and suballocates memory blocks from the larger fragment allocated by operator new when the free list is empty. Each block contains Sz * Nelts bytes of usable memory and the data required by operator new and operator delete . Selected pieces are never freed.
    • cache_chunklist - this class of templates uses operator new to allocate fragments of raw memory, to allocate blocks for allocating memory for a block of memory, when necessary; it stores the freed memory blocks in a separate free list for each fragment and uses operator delete to free the fragment when none of its memory blocks are used. Each memory block contains Sz bytes of useful memory and a pointer to the piece to which it belongs. Each block contains Nelts memory blocks, three pointers, an int, and the data that is required by operator new and operator delete .

I wrote several dispensers myself, but this documentation is just ... confusing.

+4
source share
2 answers

Wow, they really distorted the documentation, right? (I wrote this code when I was on Dinkumware)

Distributors are policy based here: you can specify a caching policy and a synchronization policy.

The basic idea is to simplify the writing of allocators that use internal caches and can be synchronized across streams. There are half a dozen predefined dispensers; their names begin with allocator_ . Use them if they suit your needs. In MSDN, consider the first paragraph of a specific dispenser description; do not read the "Notes" where they talk about ALLOCATOR_DECL

You can also use this code to create custom allocators that use predefined cache strategies (templates whose names begin with cache_ ) and synchronization strategies (templates whose names begin with sync_ ), or that use your own cache template and synchronization template. Getting a useful allocator from these parts is a bit tedious, so the header provides ALLOCATOR_DECL as a convenient way to create all the necessary templates without having to write it yourself. ALLOCATOR_DECL takes three arguments: the name of the cache template to use, the name of the synchronization template to use, and the name of the allocator you are creating. Therefore, instead of writing

 template <class T> class name : public Dinkum::allocators::allocator_base<T, sync<cache > > { public: name() {} template <class U> name(const name<U>&) {} template <class U> name& operator = (const name<U>&) {return *this; } template <class U> struct rebind { /* convert a name<T> to a name<U> */ typedef name<U> other; }; }; 

you will write ALLOCATOR_DECL(cache, sync, name); . allocator_base makes a heavy lift; the dispenser itself must be derived, so it can correctly handle rebind . ( Dinkum in this code comes from the Dinkumware documentation, I don’t know what namespace the Microsoft stuff contains, but presumably the macro puts the correct name there).

For cache templates:

  • cache_freelist maintains a linked list of node blocks; the maximum size of the list is set by the Sz template parameter, and the node is controlled using operator new and operator delete .
  • cache_suballoc adds another layer that controls the block of Nelts node blocks, all allocated as one blob; highlighting a new item first refers to the free list, and if there is nothing free, a new blob is highlighted. The memory blocks are not deleted until the allocator is destroyed.
  • cache_chunklist allocates memory in blocks (for example, cache_suballoc ), but does not use a common free list; when the block is released, it returns to the free list for its blob. When all blobs blocks have been freed, the blob itself will be deleted.
+7
source

The first subquery is easy. When to use them? When profiling shows a problem with the default allocator. This in itself makes the issue irrelevant for most developers.

Some macros use the verb "yields", which freely means "ultimately expands, possibly with a few steps."

Cache templates retain freed blocks for redistribution. You would choose the cache that best suits your allocation pattern, one that has the best tradeoff between reusing% and cache size (see Profiling above).

Some cache patterns have a finite number of freed blocks implemented through freelist<> . Max classes determine how long a freelist can be.

Distributors are finally pre-assembled combinations of the above.

0
source

Source: https://habr.com/ru/post/1440382/


All Articles