Move list in stack vs heap ?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Patrice Duhamel
Posts: 193
Joined: Sat May 25, 2013 11:17 am
Location: France
Full name: Patrice Duhamel

Move list in stack vs heap ?

Post by Patrice Duhamel »

I have a class for staged move generation data and I declare an array of this class for each ply, in the engine class.
The informations in this class are used only for current ply and I could declare it inside the search function (allocated in stack).
But I found it's slower to declare it in the search function, why so much difference in speed between the two versions ?

Default position search to depth 20 :

version A : 3 470 138 N/s
version B : 2 736 985 N/s

Code: Select all

class ChessMoveOrder {
	u32 phase;
	u32 phaseNext;
	u32 ply;
	u32 position;
	u32 pos_capture;
	ChessMove moveHash;
	ChessMove moveKiller1;		
	ChessMove moveKiller2;
	u32 count;
	ChessMoveSort movelist[MAX_PLAY_MOVES];
	// ...		
};

/////////////////////////
// * version A :

class ChessEngine {
	// ...
	ChessMoveOrder moveOrderList[MAX_DEPTH];
	// ...
	int search(int alpha, int beta, int depth, int ply);
	// ...
};

int ChessEngine::search(int alpha, int beta, int depth, int ply)
{
	// ...
	moveOrderList[ply].init( ... );
	while ((movePhase = movegen.getNextMove(moveOrderList[ply], move)) != ORDERMOVE_END) {
		// ...
	}
	// ...
}

/////////////////////////
// * version B :

int ChessEngine::search(int alpha, int beta, int depth, int ply)
{
	// ...
	ChessMoveOrder moveOrder;
	moveOrder.init( ... );
	while ((movePhase = movegen.getNextMove(moveOrder, move)) != ORDERMOVE_END) {
		// ...
	}
	// ...
}
AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Move list in stack vs heap ?

Post by AlvaroBegue »

I keep the staged move generation object in the stack, as in your version B, and I don't think it's slow at all.

How big is your class ChessMoveOrder?
Patrice Duhamel
Posts: 193
Joined: Sat May 25, 2013 11:17 am
Location: France
Full name: Patrice Duhamel

Re: Move list in stack vs heap ?

Post by Patrice Duhamel »

AlvaroBegue wrote: How big is your class ChessMoveOrder?
ChessMoveOrder size is 2084 bytes.
(ChessMove is 32 bits, ChessMoveSort 2*32 bits, and MAX_PLAY_MOVES = 256)
AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Move list in stack vs heap ?

Post by AlvaroBegue »

Patrice Duhamel wrote:
AlvaroBegue wrote: How big is your class ChessMoveOrder?
ChessMoveOrder size is 2084 bytes.
(ChessMove is 32 bits, ChessMoveSort 2*32 bits, and MAX_PLAY_MOVES = 256)
That seems reasonable. Are you by any chance doing needless work in the constructor (like memsetting the array) or in the destructor?
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Move list in stack vs heap ?

Post by Sven »

Patrice Duhamel wrote:
AlvaroBegue wrote: How big is your class ChessMoveOrder?
ChessMoveOrder size is 2084 bytes.
(ChessMove is 32 bits, ChessMoveSort 2*32 bits, and MAX_PLAY_MOVES = 256)
What does the constructor of class ChessMoveOrder do? Does it perhaps zero the whole move list array? In the latter case it would make the difference already since the constructor is run only once per array element in case of solution A, in contrast to once per node for B ...

(I now see that Álvaro has had exactly the same idea at the same time.)
Patrice Duhamel
Posts: 193
Joined: Sat May 25, 2013 11:17 am
Location: France
Full name: Patrice Duhamel

Re: Move list in stack vs heap ?

Post by Patrice Duhamel »

AlvaroBegue wrote: That seems reasonable. Are you by any chance doing needless work in the constructor (like memsetting the array) or in the destructor?
No destructor, and the constructor is empty, I only use initialization list to set other variables to zero but do nothing with the list.
kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 4:48 am

Re: Move list in stack vs heap ?

Post by kbhearn »

Do you have an initialiser list for ChessMoveSort? there are 256 of those every time you make a ChessMoveOrder - the constructor needs to be entirely empty including initialiser list.
Patrice Duhamel
Posts: 193
Joined: Sat May 25, 2013 11:17 am
Location: France
Full name: Patrice Duhamel

Re: Move list in stack vs heap ?

Post by Patrice Duhamel »

kbhearn wrote:Do you have an initialiser list for ChessMoveSort? there are 256 of those every time you make a ChessMoveOrder - the constructor needs to be entirely empty including initialiser list.
Yes, for ChessMoveSort and ChessMove, I didn't realized the cost of initializer list.

But now I have to fix some problems with non initialized value for these classes.
kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 4:48 am

Re: Move list in stack vs heap ?

Post by kbhearn »

or you can keep your preallocated structures - there shouldn't be much of a cost to that - just a bit of unused memory between the depth your search reaches and MAX_DEPTH. since it's unused it won't be in cache.
Patrice Duhamel
Posts: 193
Joined: Sat May 25, 2013 11:17 am
Location: France
Full name: Patrice Duhamel

Re: Move list in stack vs heap ?

Post by Patrice Duhamel »

kbhearn wrote:or you can keep your preallocated structures - there shouldn't be much of a cost to that - just a bit of unused memory between the depth your search reaches and MAX_DEPTH. since it's unused it won't be in cache.
Yes I could do this, but for smp I will need to preallocate it for each threads, nothing to copy between threads but more wasted memory.