OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libstdc++-v3/] [doc/] [xml/] [manual/] [allocator.xml] - Blame information for rev 745

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 742 jeremybenn
2
         xml:id="std.util.memory.allocator" xreflabel="Allocator">
3
4
 
5
Allocators
6
  
7
    
8
      ISO C++
9
    
10
    
11
      allocator
12
    
13
  
14
15
 
16
 
17
 
18
19
 Memory management for Standard Library entities is encapsulated in a
20
 class template called allocator. The
21
 allocator abstraction is used throughout the
22
 library in string, container classes,
23
 algorithms, and parts of iostreams. This class, and base classes of
24
 it, are the superset of available free store (heap)
25
 management classes.
26
27
 
28
Requirements
29
 
30
 
31
  
32
    The C++ standard only gives a few directives in this area:
33
  
34
   
35
     
36
      
37
       When you add elements to a container, and the container must
38
       allocate more memory to hold them, the container makes the
39
       request via its Allocator template
40
       parameter, which is usually aliased to
41
       allocator_type.  This includes adding chars
42
       to the string class, which acts as a regular STL container in
43
       this respect.
44
      
45
     
46
     
47
       
48
       The default Allocator argument of every
49
       container-of-T is allocator<T>.
50
       
51
     
52
     
53
       
54
       The interface of the allocator<T> class is
55
         extremely simple.  It has about 20 public declarations (nested
56
         typedefs, member functions, etc), but the two which concern us most
57
         are:
58
       
59
       
60
         T*    allocate   (size_type n, const void* hint = 0);
61
         void  deallocate (T* p, size_type n);
62
       
63
 
64
       
65
         The n arguments in both those
66
         functions is a count of the number of
67
         T's to allocate space for, not their
68
         total size.
69
         (This is a simplification; the real signatures use nested typedefs.)
70
       
71
     
72
     
73
       
74
         The storage is obtained by calling ::operator
75
         new, but it is unspecified when or how
76
         often this function is called.  The use of the
77
         hint is unspecified, but intended as an
78
         aid to locality if an implementation so
79
         desires. [20.4.1.1]/6
80
       
81
      
82
   
83
 
84
   
85
     Complete details can be found in the C++ standard, look in
86
     [20.4 Memory].
87
   
88
 
89
90
 
91
Design Issues
92
 
93
 
94
  
95
    The easiest way of fulfilling the requirements is to call
96
    operator new each time a container needs
97
    memory, and to call operator delete each time
98
    the container releases memory. This method may be slower
99
    than caching the allocations and re-using previously-allocated
100
    memory, but has the advantage of working correctly across a wide
101
    variety of hardware and operating systems, including large
102
    clusters. The __gnu_cxx::new_allocator
103
    implements the simple operator new and operator delete semantics,
104
    while __gnu_cxx::malloc_allocator
105
    implements much the same thing, only with the C language functions
106
    std::malloc and free.
107
  
108
 
109
  
110
    Another approach is to use intelligence within the allocator
111
    class to cache allocations. This extra machinery can take a variety
112
    of forms: a bitmap index, an index into an exponentially increasing
113
    power-of-two-sized buckets, or simpler fixed-size pooling cache.
114
    The cache is shared among all the containers in the program: when
115
    your program's std::vector<int> gets
116
  cut in half and frees a bunch of its storage, that memory can be
117
  reused by the private
118
  std::list<WonkyWidget> brought in from
119
  a KDE library that you linked against.  And operators
120
  new and delete are not
121
  always called to pass the memory on, either, which is a speed
122
  bonus. Examples of allocators that use these techniques are
123
  __gnu_cxx::bitmap_allocator,
124
  __gnu_cxx::pool_allocator, and
125
  __gnu_cxx::__mt_alloc.
126
  
127
 
128
  
129
    Depending on the implementation techniques used, the underlying
130
    operating system, and compilation environment, scaling caching
131
    allocators can be tricky. In particular, order-of-destruction and
132
    order-of-creation for memory pools may be difficult to pin down
133
    with certainty, which may create problems when used with plugins
134
    or loading and unloading shared objects in memory. As such, using
135
    caching allocators on systems that do not support
136
    abi::__cxa_atexit is not recommended.
137
  
138
 
139
140
 
141
Implementation
142
 
143
 
144
  
Interface Design
145
 
146
 
147
   
148
     The only allocator interface that
149
     is supported is the standard C++ interface. As such, all STL
150
     containers have been adjusted, and all external allocators have
151
     been modified to support this change.
152
   
153
 
154
   
155
     The class allocator just has typedef,
156
   constructor, and rebind members. It inherits from one of the
157
   high-speed extension allocators, covered below. Thus, all
158
   allocation and deallocation depends on the base class.
159
   
160
 
161
   
162
     The base class that allocator is derived from
163
     may not be user-configurable.
164
165
 
166
  
167
 
168
  
Selecting Default Allocation Policy
169
 
170
 
171
   
172
     It's difficult to pick an allocation strategy that will provide
173
   maximum utility, without excessively penalizing some behavior. In
174
   fact, it's difficult just deciding which typical actions to measure
175
   for speed.
176
   
177
 
178
   
179
     Three synthetic benchmarks have been created that provide data
180
     that is used to compare different C++ allocators. These tests are:
181
   
182
 
183
   
184
     
185
       
186
       Insertion.
187
       
188
       
189
       Over multiple iterations, various STL container
190
     objects have elements inserted to some maximum amount. A variety
191
     of allocators are tested.
192
     Test source for sequence
193
     and associative
194
     containers.
195
       
196
 
197
     
198
 
199
     
200
       
201
       Insertion and erasure in a multi-threaded environment.
202
       
203
       
204
       This test shows the ability of the allocator to reclaim memory
205
     on a per-thread basis, as well as measuring thread contention
206
     for memory resources.
207
     Test source
208
    here.
209
       
210
     
211
 
212
     
213
       
214
         A threaded producer/consumer model.
215
       
216
       
217
       Test source for
218
     sequence
219
     and
220
     associative
221
     containers.
222
     
223
     
224
   
225
 
226
   
227
     The current default choice for
228
     allocator is
229
     __gnu_cxx::new_allocator.
230
   
231
 
232
  
233
 
234
  
Disabling Memory Caching
235
 
236
 
237
    
238
      In use, allocator may allocate and
239
      deallocate using implementation-specified strategies and
240
      heuristics. Because of this, every call to an allocator object's
241
      allocate member function may not actually
242
      call the global operator new. This situation is also duplicated
243
      for calls to the deallocate member
244
      function.
245
    
246
 
247
   
248
     This can be confusing.
249
   
250
 
251
   
252
     In particular, this can make debugging memory errors more
253
     difficult, especially when using third party tools like valgrind or
254
     debug versions of new.
255
   
256
 
257
   
258
     There are various ways to solve this problem. One would be to use
259
     a custom allocator that just called operators
260
     new and delete
261
     directly, for every allocation. (See
262
     include/ext/new_allocator.h, for instance.)
263
     However, that option would involve changing source code to use
264
     a non-default allocator. Another option is to force the
265
     default allocator to remove caching and pools, and to directly
266
     allocate with every call of allocate and
267
     directly deallocate with every call of
268
     deallocate, regardless of efficiency. As it
269
     turns out, this last option is also available.
270
   
271
 
272
 
273
   
274
     To globally disable memory caching within the library for the
275
     default allocator, merely set
276
     GLIBCXX_FORCE_NEW (with any value) in the
277
     system's environment before running the program. If your program
278
     crashes with GLIBCXX_FORCE_NEW in the
279
     environment, it likely means that you linked against objects
280
     built against the older library (objects which might still using the
281
     cached allocations...).
282
  
283
 
284
  
285
 
286
287
 
288
Using a Specific Allocator
289
 
290
 
291
   
292
     You can specify different memory management schemes on a
293
     per-container basis, by overriding the default
294
     Allocator template parameter.  For example, an easy
295
      (but non-portable) method of specifying that only malloc or free
296
      should be used instead of the default node allocator is:
297
   
298
   
299
    std::list <int, __gnu_cxx::malloc_allocator<int> >  malloc_list;
300
    
301
      Likewise, a debugging form of whichever allocator is currently in use:
302
    
303
      
304
    std::deque <int, __gnu_cxx::debug_allocator<std::allocator<int> > >  debug_deque;
305
      
306
307
 
308
Custom Allocators
309
 
310
 
311
  
312
    Writing a portable C++ allocator would dictate that the interface
313
    would look much like the one specified for
314
    allocator. Additional member functions, but
315
    not subtractions, would be permissible.
316
  
317
 
318
   
319
     Probably the best place to start would be to copy one of the
320
   extension allocators: say a simple one like
321
   new_allocator.
322
   
323
 
324
325
 
326
Extension Allocators
327
 
328
 
329
  
330
    Several other allocators are provided as part of this
331
    implementation.  The location of the extension allocators and their
332
    names have changed, but in all cases, functionality is
333
    equivalent. Starting with gcc-3.4, all extension allocators are
334
    standard style. Before this point, SGI style was the norm. Because of
335
    this, the number of template arguments also changed. Here's a simple
336
    chart to track the changes.
337
  
338
 
339
  
340
    More details on each of these extension allocators follows.
341
  
342
   
343
     
344
       
345
       new_allocator
346
       
347
       
348
         Simply wraps ::operator new
349
         and ::operator delete.
350
       
351
     
352
     
353
       
354
       malloc_allocator
355
       
356
       
357
         Simply wraps malloc and
358
         free. There is also a hook for an
359
         out-of-memory handler (for
360
         new/delete this is
361
         taken care of elsewhere).
362
       
363
     
364
     
365
       
366
       array_allocator
367
       
368
       
369
         Allows allocations of known and fixed sizes using existing
370
         global or external storage allocated via construction of
371
         std::tr1::array objects. By using this
372
         allocator, fixed size containers (including
373
         std::string) can be used without
374
         instances calling ::operator new and
375
         ::operator delete. This capability
376
         allows the use of STL abstractions without runtime
377
         complications or overhead, even in situations such as program
378
         startup. For usage examples, please consult the testsuite.
379
       
380
     
381
     
382
       
383
       debug_allocator
384
       
385
       
386
         A wrapper around an arbitrary allocator A.  It passes on
387
         slightly increased size requests to A, and uses the extra
388
         memory to store size information.  When a pointer is passed
389
         to deallocate(), the stored size is
390
         checked, and assert() is used to
391
         guarantee they match.
392
       
393
     
394
      
395
        
396
        throw_allocator
397
        
398
        
399
          Includes memory tracking and marking abilities as well as hooks for
400
          throwing exceptions at configurable intervals (including random,
401
          all, none).
402
        
403
      
404
     
405
       
406
       __pool_alloc
407
       
408
       
409
         A high-performance, single pool allocator.  The reusable
410
         memory is shared among identical instantiations of this type.
411
         It calls through ::operator new to
412
         obtain new memory when its lists run out.  If a client
413
         container requests a block larger than a certain threshold
414
         size, then the pool is bypassed, and the allocate/deallocate
415
         request is passed to ::operator new
416
         directly.
417
       
418
 
419
       
420
         Older versions of this class take a boolean template
421
         parameter, called thr, and an integer template
422
         parameter, called inst.
423
       
424
 
425
       
426
         The inst number is used to track additional memory
427
      pools.  The point of the number is to allow multiple
428
      instantiations of the classes without changing the semantics at
429
      all.  All three of
430
       
431
 
432
   
433
    typedef  __pool_alloc<true,0>    normal;
434
    typedef  __pool_alloc<true,1>    private;
435
    typedef  __pool_alloc<true,42>   also_private;
436
   
437
   
438
     behave exactly the same way.  However, the memory pool for each type
439
      (and remember that different instantiations result in different types)
440
      remains separate.
441
   
442
   
443
     The library uses 0 in all its instantiations.  If you
444
      wish to keep separate free lists for a particular purpose, use a
445
      different number.
446
   
447
   The thr boolean determines whether the
448
   pool should be manipulated atomically or not.  When
449
   thr = true, the allocator
450
   is thread-safe, while thr =
451
   false, is slightly faster but unsafe for
452
   multiple threads.
453
   
454
 
455
   
456
     For thread-enabled configurations, the pool is locked with a
457
     single big lock. In some situations, this implementation detail
458
     may result in severe performance degradation.
459
   
460
 
461
   
462
     (Note that the GCC thread abstraction layer allows us to provide
463
     safe zero-overhead stubs for the threading routines, if threads
464
     were disabled at configuration time.)
465
   
466
     
467
 
468
     
469
       
470
       __mt_alloc
471
       
472
       
473
         A high-performance fixed-size allocator with
474
         exponentially-increasing allocations. It has its own
475
         documentation, found here.
476
       
477
     
478
 
479
     
480
       
481
       bitmap_allocator
482
       
483
       
484
         A high-performance allocator that uses a bit-map to keep track
485
         of the used and unused memory locations. It has its own
486
         documentation, found here.
487
       
488
     
489
   
490
491
 
492
 
493
Bibliography
494
 
495
 
496
  
497
    
498
    ISO/IEC 14882:1998 Programming languages - C++
499
    
500
    
501
      isoc++_1998
502
    
503
    20.4 Memory
504
  
505
 
506
  
507
      </code></pre></td>
      </tr>
      <tr valign="middle">
         <td>508</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        <link xmlns:xlink="http://www.w3.org/1999/xlink"</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>509</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>              xlink:href="http://www.drdobbs.com/cpp/184403759"></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>510</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      The Standard Librarian: What Are Allocators Good For?</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>511</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        </link></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>512</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      
513
 
514
    MattAustern
515
    
516
      
517
        C/C++ Users Journal
518
      
519
    
520
  
521
 
522
  
523
      </code></pre></td>
      </tr>
      <tr valign="middle">
         <td>524</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        <link xmlns:xlink="http://www.w3.org/1999/xlink"</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>525</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>              xlink:href="http://www.cs.umass.edu/~emery/hoard"></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>526</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      The Hoard Memory Allocator</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>527</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        </link></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>528</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      
529
 
530
    EmeryBerger
531
  
532
 
533
  
534
      </code></pre></td>
      </tr>
      <tr valign="middle">
         <td>535</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        <link xmlns:xlink="http://www.w3.org/1999/xlink"</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>536</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>              xlink:href="http://www.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf"></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>537</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      Reconsidering Custom Memory Allocation</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>538</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        </link></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>539</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      
540
 
541
    EmeryBerger
542
    BenZorn
543
    KathrynMcKinley
544
    
545
      2002
546
      OOPSLA
547
    
548
  
549
 
550
 
551
  
552
      </code></pre></td>
      </tr>
      <tr valign="middle">
         <td>553</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        <link xmlns:xlink="http://www.w3.org/1999/xlink"</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>554</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>              xlink:href="http://www.angelikalanger.com/Articles/C++Report/Allocators/Allocators.html"></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>555</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      Allocator Types</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>556</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>        </link></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>557</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>      
558
 
559
 
560
    KlausKreft
561
    AngelikaLanger
562
    
563
      
564
        C/C++ Users Journal
565
      
566
    
567
  
568
 
569
  
570
    The C++ Programming Language
571
    BjarneStroustrup
572
    
573
      2000
574
      
575
    
576
    19.4 Allocators
577
    
578
      
579
        Addison Wesley
580
      
581
    
582
  
583
 
584
  
585
    Yalloc: A Recycling C++ Allocator
586
    FelixYen
587
  
588
589
 
590

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.