473,769 Members | 7,408 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Optimal buffer growth

Hi,

I remember reading in a book (or in an article) that the optmial buffer
growth factor is about 1.6. Now I need to find this book but I can't
remember its title. Can someone help me with this?
Jun 27 '08 #1
6 2403
On Jun 18, 2:45 pm, "Angel Tsankov" <fn42...@fmi.un i-sofia.bgwrote:
Hi,

I remember reading in a book (or in an article) that the optmial buffer
growth factor is about 1.6. Now I need to find this book but I can't
remember its title. Can someone help me with this?
I think you are thinking Andrew Koenig.

Search for the thread titled "vector growth factor of 1.5" at
groups.google.c om for a discussion of it.

Ali
Jun 27 '08 #2
Angel Tsankov wrote:
I remember reading in a book (or in an article) that the optmial buffer
growth factor is about 1.6. Now I need to find this book but I can't
remember its title. Can someone help me with this?
What do you mean by "optimal"? It's a space-time tradeoff. If you increase
the multiplication factor, you decrease the expected number of move or copy
operations but you increase the expected memory overhead.

Assuming that the capacity multiplies by a factor of d 1 at each
reallocation, I get (using Benford's law):

a) The expected ratio size() / capacity() is:

d - 1
--------- (for d = 2, approx = 0.72)
d ln(d)
b) Filling the vector by a series of push_back() operations will involve on
average

1
------- (for d = 2, approx = 1.44)
ln(d)

moves per object arising from reallocating the vector (i.e., not including
initial copy construction of the object into the vector).
For d = 1.6, that would be an expected memory usage of 80% and each object
would be reallocated 2.13 times on average.
Best

Kai-Uwe Bux
Jun 27 '08 #3
>Hi,
>>
I remember reading in a book (or in an article) that the optmial buffer
growth factor is about 1.6. Now I need to find this book but I can't
remember its title. Can someone help me with this?

I think you are thinking Andrew Koenig.

Search for the thread titled "vector growth factor of 1.5" at
groups.google.c om for a discussion of it.
Thanks a lot for the reference; I'll take a look. However, I still need to
find out that book...
Jun 27 '08 #4
On Jun 19, 1:16 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
Angel Tsankov wrote:
I remember reading in a book (or in an article) that the
optmial buffer growth factor is about 1.6. Now I need to
find this book but I can't remember its title. Can someone
help me with this?
What do you mean by "optimal"? It's a space-time tradeoff. If
you increase the multiplication factor, you decrease the
expected number of move or copy operations but you increase
the expected memory overhead.
The issue was that if the factor is larger than (1+sqrt(5))/2
(roughly 1.618), the memory freed after a reallocation could
never be reused by the vector; if you double the size at each
allocation, the total memory freed until that point will always
be less than the size requested for the new allocation. If the
factor is smaller, you can hope that sooner or later, the
underlying allocator will be able to merge previously filled
blocks, and fulfill the request from them.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #5
James Kanze wrote:
On Jun 19, 1:16 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
>Angel Tsankov wrote:
I remember reading in a book (or in an article) that the
optmial buffer growth factor is about 1.6. Now I need to
find this book but I can't remember its title. Can someone
help me with this?
>What do you mean by "optimal"? It's a space-time tradeoff. If
you increase the multiplication factor, you decrease the
expected number of move or copy operations but you increase
the expected memory overhead.

The issue was that if the factor is larger than (1+sqrt(5))/2
(roughly 1.618), the memory freed after a reallocation could
never be reused by the vector; if you double the size at each
allocation, the total memory freed until that point will always
be less than the size requested for the new allocation. If the
factor is smaller, you can hope that sooner or later, the
underlying allocator will be able to merge previously filled
blocks, and fulfill the request from them.
Cool, the golden ratio strikes again.

I have to wonder, though, whether this has a measurable impact (a) on modern
architectures where memory is organized in pages or (b) in typical programs
where one probably has more than one dynamic data structure growing at a
time anyway.
Best

Kai-Uwe Bux
Jun 27 '08 #6
On Jun 19, 3:14 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
James Kanze wrote:
On Jun 19, 1:16 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
Angel Tsankov wrote:
I remember reading in a book (or in an article) that the
optmial buffer growth factor is about 1.6. Now I need to
find this book but I can't remember its title. Can someone
help me with this?
What do you mean by "optimal"? It's a space-time tradeoff. If
you increase the multiplication factor, you decrease the
expected number of move or copy operations but you increase
the expected memory overhead.
The issue was that if the factor is larger than (1+sqrt(5))/2
(roughly 1.618), the memory freed after a reallocation could
never be reused by the vector; if you double the size at each
allocation, the total memory freed until that point will always
be less than the size requested for the new allocation. If the
factor is smaller, you can hope that sooner or later, the
underlying allocator will be able to merge previously filled
blocks, and fulfill the request from them.
Cool, the golden ratio strikes again.
I have to wonder, though, whether this has a measurable impact
(a) on modern architectures where memory is organized in pages
or (b) in typical programs where one probably has more than
one dynamic data structure growing at a time anyway.
I don't really know. Nominally, with any of the "classical"
allocation algorithms, if you have one vector which just grows
and grows, it eventually migrates to the end of the free space
arena (because it becomes bigger than any of the holes), and
this factor could possibly affect just how large you could make
it grow. Except, of course, that you'll likely bring the
machine to its knees through paging before that. And that there
are enough additional factors involved that it's not certain
that the rule really changes anything.

Just out of curiousity, during my lunch hour, I wrote a simple
allocator and tested the principles. Using some simple
multipliers, I get the following output:
For 1.10: max size = 389582583 (39.0%)
For 1.20: max size = 389586745 (39.0%)
For 1.30: max size = 513088587 (51.3%)
For 1.40: max size = 477760691 (47.8%)
For 1.50: max size = 419279977 (41.9%)
For 1.60: max size = 432051256 (43.2%)
For 1.70: max size = 360273482 (36.0%)
For 1.80: max size = 307547665 (30.8%)
For 1.90: max size = 328691801 (32.9%)
For 2.00: max size = 268435456 (26.8%)
Change just about any of the parmeters, however, and you get
something different: using an initial size of 500 (rather than
128) results in:
For 1.10: max size = 374691238 (37.5%)
For 1.20: max size = 519586870 (52.0%)
For 1.30: max size = 420105341 (42.0%)
For 1.40: max size = 488743519 (48.9%)
For 1.50: max size = 323374783 (32.3%)
For 1.60: max size = 259493561 (25.9%)
For 1.70: max size = 288397093 (28.8%)
For 1.80: max size = 371637543 (37.2%)
For 1.90: max size = 357024500 (35.7%)
For 2.00: max size = 262144000 (26.2%)
Change the size of the arena from 1000000000 to 500000000, and
you get:
For 1.10: max size = 219909214 (44.0%)
For 1.20: max size = 225455293 (45.1%)
For 1.30: max size = 233540550 (46.7%)
For 1.40: max size = 174111040 (34.8%)
For 1.50: max size = 279519985 (55.9%)
For 1.60: max size = 168770022 (33.8%)
For 1.70: max size = 124662105 (24.9%)
For 1.80: max size = 170859814 (34.2%)
For 1.90: max size = 172995685 (34.6%)
For 2.00: max size = 134217728 (26.8%)
For the moment, I'm not sure what one can really conclude:-).

Anyhow, for those interested, here's the code. It uses my
library, but only a few simple things from it, which can easily
be replaced. Also, it's entirely possible that I've got an
error somewhere in it (it was written very quickly), which could
explain the randomness of the results as well.

-------------- fill.cc ----------------
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <new>
#include "gb/FFmt.hh"
#include "gb/CommandLine.hh"
#include "gb/NumericOption.h h"

Gabi::BoundNume ricOption
arenaSize( 'a', 1000000000 ) ;
Gabi::BoundNume ricOption
startSize( 's', 128 ) ;
Gabi::BoundNume ricOption
intervalCount( 'i', 10 ) ;

class Pool
{
public:
explicit Pool( size_t size = arenaSize ) ;
~Pool() ;
void* allocate( size_t n ) ;
void free( void* p ) ;

private:
struct BlockHeader
{
BlockHeader* next ;
bool isFree ;
} ;
void* base ;
BlockHeader* first ;

inline void* add( void* p, size_t n )
{
return static_cast< char* >( p ) + n ;
}
inline size_t diff( void* p1, void* p2 )
{
return static_cast< char* >( p2 ) - static_cast< char*
>( p1 ) ;
}
} ;

void
testPool(
double ratio )
{
Pool p ;
size_t s = startSize ;
void* v = p.allocate( s ) ;
while ( v != NULL ) {
size_t s2 = (size_t)( ratio * s ) ;
void* v2 = p.allocate( s2 ) ;
p.free( v ) ;
v = v2 ;
if ( v != NULL ) {
s = s2 ;
}
}
std::cout << "For " << Gabi::FFmt( 4, 2 ) << ratio
<< ": max size = " << std::setw( 9 ) << s
<< " (" << Gabi::FFmt( 4, 1 ) << 100.0 * s / arenaSize
<< "%)"
<< std::endl ;
}

int
main( int argc, char** argv )
{
Gabi::CommandLi ne::instance(). parse( argc, argv ) ;
for ( int i = 1 ; i <= intervalCount ; ++ i ) {
testPool( 1.0 + i / static_cast< double
>( intervalCount.v alue() ) ) ;
}
return 0 ;
}

Pool::Pool(
size_t size )
{
base = std::malloc( size ) ;
if ( base == NULL ) {
throw std::bad_alloc( ) ;
}
first = static_cast< BlockHeader* >( base ) ;
BlockHeader* last
= static_cast< BlockHeader* >(
add( first, size - sizeof( BlockHeader ) ) ) ;
first->next = last ;
first->isFree = true ;
last->next = NULL ;
last->isFree = false ;
}

Pool::~Pool()
{
std::free( base ) ;
}

void*
Pool::allocate(
size_t n )
{
n += sizeof( BlockHeader ) ;
n = (n + 7) & (static_cast< size_t >( -1 ) << 3) ;
BlockHeader* result = NULL ;
BlockHeader* b = first ;
while ( result == NULL && b != NULL ) {
if ( b->isFree ) {
while ( b->next->isFree ) {
b->next = b->next->next ;
}
if ( diff( b, b->next ) n ) {
result = b ;
}
}
b = b->next ;
}
if ( result != NULL ) {
if ( diff( result, result->next ) n +
sizeof( BlockHeader ) ) {
BlockHeader* newNext
= static_cast< BlockHeader* >( add( result,
n ) ) ;
newNext->next = result->next ;
newNext->isFree = true ;
result->next = newNext ;
}
result->isFree = false ;
++ result ;
}
return result ;
}

void
Pool::free(
void* p )
{
if ( p != NULL ) {
BlockHeader* b = static_cast< BlockHeader* >( p ) - 1 ;
b->isFree = true ;
}
}
---------------- ------- ----------------

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
9742
by: Amy L. | last post by:
Is there a Buffer size that is optimial based on the framework or OS that is optimal when working with chunks of data? Also, is there a point where the buffer size might not be optimal (too large)? I am considering an 8K or 16K Buffer. The files sizes are random but range between 8K - 100K with the occasional files being several megs. Example: int _READBUFFER_ = 1024 ; fi = new FileInfo( args ) ;
18
7352
by: junky_fellow | last post by:
Hi all, Is there any way by which we mat determine the direction of stack growth (from higher address to lower address Or from lower address to higher address) ? I know this question is implementation specific and this may not be the correct place to ask this. But any hints would help me a lot.
2
6784
by: Kiran | last post by:
Hello Everybody! I am writing a networking application in python for a small piece of hardware, in which there could sometimes be timeouts. I am using sockets to communicate to this device. Data that is sent to the device is instructions for that piece of hardware, and data recieved is just responses from that hardware. When a timeout happens, for some reason extra data is stored inside the buffer, so when the timeout is over, that...
6
1496
by: nickdu | last post by:
I usually try to stay away from _alloca(). However, I'm considering using it for a logging function. Our current logging function maintains its own buffer which it grows to fit the string being logged. To work correctly in a multi-threaded environment there are locks around the code which log the string. We could remove the locks and just allocate on the heap, but then we could run into heap contention and heap fragmentation. We could...
28
3880
by: bwaichu | last post by:
Is it generally better to set-up a buffer (fixed sized array) and read and write to that buffer even if it is larger than what is being written to it? Or is it better to allocate memory and realloc it for the size of the what is being written each time? In other words, what is the decision factor between deciding to use a fixed size buffer or allocating memory space and reallocing the size? I don't think the code below is optimal...
64
9762
by: Philip Potter | last post by:
Hello clc, I have a buffer in a program which I write to. The buffer has write-only, unsigned-char-at-a-time access, and the amount of space required isn't known a priori. Therefore I want the buffer to dynamically grow using realloc(). A comment by Richard Heathfield in a thread here suggested that a good algorithm for this is to use realloc() to double the size of the buffer, but if realloc() fails request smaller size increments...
0
1458
by: Lambda | last post by:
I'd like to write compressed data to a file. To improve performance, I want to use buffer. I read some books, they all talk about 'character' stream. But I think compressed data should be binary. And, what buffer size if optimal? How can I set the buffer size? I need to checkpoint the buffer when
0
2435
by: Kozy | last post by:
Hello everyone, i have a big problem with imports. I have only see this problem on 9.5, i have never goten it on 9.1. 99% of time db2 works great ( version 9.5 fixpack 5 ) on windows 2008 ( microsoft cluster solution ). When we do imports we get the following error ( once in a while ... but it is frequent enough to worry us ). Error from log:
0
9589
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
9996
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9865
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8872
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6674
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5304
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5447
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3563
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.