GCC 4.8 made me chose Clang

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
trojanfoe
Posts: 65
Joined: Sun Jul 31, 2011 11:57 am
Location: Waterlooville, Hampshire, UK

Re: GCC 4.8 made me chose Clang

Post by trojanfoe »

abulmo wrote:
trojanfoe wrote: Apple clang 5.0
What is this version? The latest version I can found on internet is only 3.4. Is this really clang version or just the latest XCode version ?
This is the version that Apple provide with Xcode. It's based off LLVM 3.3svn with unknown modifications from Apple:

Code: Select all

$ clang --version
Apple LLVM version 5.0 (clang-500.2.78) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: GCC 4.8 made me chose Clang

Post by Rein Halbersma »

mar wrote:
Rein Halbersma wrote:For C++11, my preferred option is using a std::vector with a flexible and quite well performing arena allocator. This will allocate from a stack-based fixed-sized buffer, and go to the heap when that runs out. Overhead per allcoation is a conditional (check if pointer is inside buffer) and a pointer increment.
Why do things in a simple and effecient way when there is always an ugly bloated solution :) I would kill for that.
Do you realize that the code is actually broken?
It doesn't align the allocs.
So if you use the same "arena" to allocate 3 bytes then one 32-bit int on ARM, you will get an exception once you try to access it.
But allocating heterogeneous types of different alignments is not the use case for allocators. See here for example code:

http://home.roadrunner.com/~hinnant/stack_alloc.html

Instead, the use case is to have a variable move_list of type std::vector<move_t, short_alloc<move_t, N * sizeof(move_t)>> to store the generated moves in through a sequence of calls to move_list.push_back(current_moves). As long as the number of generated moves stays below 128 (or whatever number you like), this will only increment pointers into an arena object which is a thin wrapper around a stack-allocated char[128*sizeof(move_t)]. Only when the array has been exhausted, will the allocator go to the heap for additional memory. So it's both efficient and safe to use with arbitrary large move lists.
mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: GCC 4.8 made me chose Clang

Post by mar »

Rein Halbersma wrote:But allocating heterogeneous types of different alignments is not the use case for allocators.
Yes I understand the use case. The problem is that misuse of arena can break things (badly).
What's more important about vector is that it grows by powers of two when using push_back.
So you not only waste performance by copying/moving elements each time you push 2^n-th element (negligible),
but more importantly you waste the preallocated space (using 128*sizeof(int32_t) you are out stack memory already when pushing 29th element!!!).
reserve() and push_back would be much better and resize() would be best if you know in advance how much space you'll need.
Either way this solution is by far no replacement for VLAs and doesn't justify the added complexity.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: GCC 4.8 made me chose Clang

Post by Rein Halbersma »

mar wrote:
Rein Halbersma wrote:But allocating heterogeneous types of different alignments is not the use case for allocators.
Yes I understand the use case. The problem is that misuse of arena can break things (badly).
What's more important about vector is that it grows by powers of two when using push_back.
So you not only waste performance by copying/moving elements each time you push 2^n-th element (negligible),
but more importantly you waste the preallocated space (using 128*sizeof(int32_t) you are out stack memory already when pushing 29th element!!!).
reserve() and push_back would be much better and resize() would be best if you know in advance how much space you'll need.
Well of course, you need to use move_list.reserve(128) once before you start pushing back moves (and that only adjusts a pointer, does not allocate anything). That way, the only time you are copying is when you are going to the heap anyway. There really is no overhead except for the conditional to check whether there is enough stack space left.
Either way this solution is by far no replacement for VLAs and doesn't justify the added complexity.
It's more complexity, granted, and for games like chess where you can infer the number of moves from popcounting bit patterns, VLAs are probably the preferred solution.

But for games like draughts, you need a recursive search to find multiple captures and these can grow pretty large (there are positions in 10x10 international draughts that have > 500 moves). Moreoever, it's not possible to infer the total number from popcounting alone. So for that, the flexibility of a std::vector + stack allocator is really an efficient solution, even if it requires a few extra statement to set up the arena and allocator.
User avatar
jshriver
Posts: 1342
Joined: Wed Mar 08, 2006 9:41 pm
Location: Morgantown, WV, USA

Re: GCC 4.8 made me chose Clang

Post by jshriver »

You should be able to install older versions of gcc, then just change your MAkefile to use CC=gcc-4.7 instead of the default gcc

Believe gcc itself is just a symlink to whatever the current gcc-X.Y is.

I've had to do this in the past for code that wouldnt compile in 4.7 but worked well in 4.4

-Josh

apt-cache search gcc 4.7