简体   繁体   中英

More efficient creation of objects and object arrays in a recursive function? C++

I'm currently writing a chess engine, and recently profiled it. I was pretty surprised to see that the second most expensive operation (aside from the search function itself) is the creation of my move generation object, barely below my evaluation function. I'm relatively new to programming, so there's more than likely a much better way of doing what I'm doing currently.

As it stands, the move generation object is initialized right before the moves loop in the search function, and the bitboards are copied over from my bitboard object(which costs nothing compared to the const of creating the object itself).

Here's the header file for the moveGeneration object, it contains an array of move objects(which the creation of is pretty expensive as well) I've also left out the functions for ease of viewing, I can post them if need be though.

class MoveGen
{
public:
MoveGen();

//array of move objects 
Move moveAr[256];

bool isWhite;
//number of moves generated this node
int moveCount;

//bitboards
    U64 FullTiles;
    U64 EmptyTiles;
    U64 BBWhitePieces;
    U64 BBWhitePawns;
    U64 BBWhiteRooks;
    U64 BBWhiteKnights;
    U64 BBWhiteBishops;
    U64 BBWhiteQueens;
    U64 BBWhiteKing;
    U64 BBBlackPieces;
    U64 BBBlackPawns;
    U64 BBBlackRooks;
    U64 BBBlackKnights;
    U64 BBBlackBishops;
    U64 BBBlackQueens;
    U64 BBBlackKing;
};

For completeness, here's the the Move object info:

class Move
{
public:
Move();

U8 from;
U8 to;
char piece;
char captured;
int score;
U8 flag;
bool tried;
};

Move::Move(){
     tried = false;
}

Is there anything glaringly obvious that I could do to speed up the creation of the move generation object? I'm open to a complete re-work of anything, as this is a huge drain on the speed of my program.

I've thought about removing the local bitboards inside the MoveGen class and just passing a const & of the bitboards object to the MoveGen functions. Although I think the main slowdown is coming from the creation of the object array. MoveGen::MoveGen has 23.18% inclusive samples in my profiling, and Move::Move has 11.31%, both very high compared to everything but the search itself.

I apologize if this is too general a question and I'll delete it if that's the case. Any advice on a more efficient way to do this would be much appreciated though!

it contains an array of move objects(which the creation of is pretty expensive as well)

Based on that alone it's in your best interest to allocate however many MoveGen objects you need up front before entering the recursive function. This means you have two options, allocate from the heap, or in the stack before the function call. Allocating up front and passing pointers around is way faster than creating big objects repeatedly in a loop.

As several commenters have noted, the high percentage is because you're repeatedly constructing MoveGen objects, requiring the construction of 256 Move objects each time, and your Move objects are expensive. This is because every type with a non-trivial constructor(basically, user-defined) must be constructed in place after being allocated. Fields in a class are allocated when the containing class is allocated, in each recursive call in your case. If you don't do this yourself for non-trivial types the compiler will do it for you to ensure your objects are correctly initialized, which is what's happening in your code.

In general, you always want to pre-allocate as much as possible, especially in the case of big and/or expensive objects.

The suggestion from John Zwinck of inlining the constructor for Move as well as removing the constructor for MoveGen did the trick. While it was a moderate increase in performance, the two constructors that previously showed as very intensive in profiling no longer do. Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM