From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ad4585f2971e47c5 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!postnews.google.com!l11g2000yqb.googlegroups.com!not-for-mail From: jonathan Newsgroups: comp.lang.ada Subject: Re: Need some light on using Ada or not Date: Sun, 20 Feb 2011 08:42:06 -0800 (PST) Organization: http://groups.google.com Message-ID: <6a387d75-a319-4584-8f26-72dee661e1ba@l11g2000yqb.googlegroups.com> References: <4d5ef836$0$23753$14726298@news.sunsite.dk> <7ibvl6tn4os3njo3p4kek9kop44nke3n7t@4ax.com> <4d5fd57d$0$6992$9b4e6d93@newsspool4.arcor-online.net> NNTP-Posting-Host: 143.117.23.236 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 X-Trace: posting.google.com 1298220126 11245 127.0.0.1 (20 Feb 2011 16:42:06 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Sun, 20 Feb 2011 16:42:06 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: l11g2000yqb.googlegroups.com; posting-host=143.117.23.236; posting-account=Jzt5lQoAAAB4PhTgRLOPGuTLd_K1LY-C User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.19) Gecko/2010120923 Iceweasel/3.0.6 (Debian-3.0.6-3),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:18461 Date: 2011-02-20T08:42:06-08:00 List-Id: > On Sat, 19 Feb 2011 15:36:45 +0100, Georg Bauhaus > > C #includes , that is, it exercises the Apache memory pool, > not what is available with plain C. > > C++ #includes a similar thing from the Boost libraries. On Feb 19, 6:25 pm, Brian Drummond wrote: > > even though you are not allowed to supply your own pool. > Possibly harsh, but I can see the logic behind it. > Free lists are forbidden also. The rules could not be clearer: Please don't implement your own custom memory pool or free list. A few more observations. First a minor point: On my machine I can make the Ada version the same speed as the (single core) C#1 and the C++#2 (about 10% faster) with a small change (I placed the patch at the end of post). Now a not so minor point: the (single core) gcc compilations, Ada and C#1 and C++#2 are doing the same things and running the same rate. They are allocating the same amount of memory the same number of times and deallocating the same amount of memory the same number of times. So here's the puzzle. How do the C#7 and C++#6 programs (single core) run so much faster. Can we speed up X number of calls to "new" and Y calls to "Unchecked_Deallocation" without reducing X or Y? The C++#6 uses the Boost library's "object_pool.hpp", so I suggest we go straight to the magical source code: http://sourceforge.net/projects/boost/files/boost/1.45.0/ Find the file here: boost_1_45_0/boost/pool/object_pool.hpp Find the destructor, ~object_pool(); Now do a search for "free list", and you'll find things like: // Start 'freed_iter' at beginning of free list void * freed_iter = this->first; // Increment freed_iter to point to next in free list freed_iter = nextof(freed_iter); Free lists. Oh what a shock. The fastest C program, C#7, links to the apache run-time system memory pool. To find out what it does, just google "apr_pools.h", and click away. The inner loop of the C#7 benchmark uses a call to "apr_pool_clear" to deallocate the memory: void apr_pool_clear (apr_pool_t * p) Remarks: This does not actually free the memory, it just allows the pool to re-use this memory for the next allocation. So it turns out that no memory at all is deallocated in the C#7 benchmark's inner loop. In the original benchmark, this inner loop is where the memory is actually freed. For example, in the Ada version this inner loop is where all the Unchecked_Deallocations are called. But in the C#7 version, the deallocation is moved outside of the benchmarking loop to a call to "apr_pool_destroy": void apr_pool_destroy (apr_pool_t * p) Destroy the pool. This takes similar action as apr_pool_clear() and then frees all the memory. Remarks: This will actually free the memory. I don't read C/C++ with any confidence, but it looks to me like they get their faster-than-light performance by dispensing with calls to Unchecked_Deallocation. J. * the small change: replace Short_Lived_Tree_1 := Bottom_Up_Tree (Item => I, Depth => d); Short_Lived_Tree_2 := Bottom_Up_Tree (Item =>-I, Depth => d); Item_Check (Short_Lived_Tree_1, Sum); Check := check + Sum; Item_Check (Short_Lived_Tree_2, Sum); Check := Check + Sum; with -- allocate new memory: Short_Lived_Tree_1 := Bottom_Up_Tree (Item => I, Depth => d); --Free mem allocated to Tree_2: Item_Check (Short_Lived_Tree_1, Sum); Check := check + Sum; -- allocate new memory: Short_Lived_Tree_2 := Bottom_Up_Tree (Item =>-I, Depth => d); --Free mem allocated to Tree_2: Item_Check (Short_Lived_Tree_2, Sum); Check := Check + Sum;