好的,伙计们:内存优化绝对不是我的事,因为我目前正在从事一个大型、cpu 和内存密集型项目,我想我需要你的帮助。
该项目是一个国际象棋引擎,实际问题(我猜)在于以下两种方法之一(上面的代码不是100%准确,但或多或少):
树搜索 ( MiniMax ) - 实际代码是带有不同添加的 Alpha-Beta,但这个非常基本的示例更具说明性:
int Board::miniMax_(int ply)
{
if (ply == this->searchDepth) return this->eval();
int best = MINUS_INF;
vector<Move*> moves = this->possibleMoves();
FOREACH(Move*, move, moves)
{
HASHMAKE((*move),this);
int val = -this->miniMax_(ply+1);
UNHASHMAKE((*move),this);
if (val>best) {
if (ply==0) this->bestMove = (*move);
best = val;
}
}
return best;
}
移动生成 (如果您从未玩过国际象棋编程和位板,以下内容可能看起来几乎毫无意义;但您仍然会在内存处理方面有所了解 - 嗯,希望......):
vector<Move*> Board::possibleMoves()
{
U64 ownPieces = this->piecesForColor(this->playing);
U64 occupied = ~(this->pieces[empty]);
vector<Move*> moves;
//-----------------------------------------
// "Normal" Piece Moves
//-----------------------------------------
const int from = (1+(this->playing))*3;
const int to = (1+(this->playing))*3+6;
for (int pieceType=from; pieceType<to; pieceType++)
{
U64 piece = this->pieces[pieceType];
for (; piece != 0; piece &= (piece - 1))
{
UINT pos = log2(piece & ~(piece-1));
U64 move;
switch (pieceType)
{
case bPawns: move = BPAWN_(pos,ownPieces,occupied); break;
case wPawns: move = WPAWN_(pos,ownPieces,occupied); break;
case bRooks:
case wRooks: move = ROOK_(pos,ownPieces,occupied); break;
case bKnights:
case wKnights: move = KNIGHT_(pos,ownPieces,occupied); break;
case bBishops:
case wBishops: move = BISHOP_(pos,ownPieces,occupied); break;
case bQueen:
case wQueen: move = QUEEN_(pos,ownPieces,occupied); break;
case bKing:
case wKing: move = KING_(pos,ownPieces,occupied); break;
default:break;
}
for (; move !=0; move &= (move-1))
{
moves += new Move(pos, log2(move&~(move-1)),this);
}
}
}
return moves;
}
移动类
//=======================================================
// Prototype
//=======================================================
class Move
{
public:
Move (string m, Board* b) : from(ALG2FROM(m)), to(ALG2TO(m)), pieceFrom(b->atPosition[from]), pieceTo(b->atPosition[to]) {}
Move (int f, int t, Board* b) : from(f), to(t), pieceFrom(b->atPosition[from]), pieceTo(b->atPosition[to]) {}
Move (int val) : value(val) {}
inline string notation();
inline string out();
//----------------------
int from, to;
int pieceFrom, pieceTo;
int value;
};
//=======================================================
// Inline Functions
//=======================================================
inline string Move::notation()
{
return SSTR(SPOS(this->from) << SPOS(this->to));
}
inline string Move::out()
{
return SSTR(this->notation() << " :: " << this->value);
}
显然,第一个函数被递归并调用了数百万次,有一些预期的负载。问题是一旦搜索到第 4 层、第 5 层或其他东西,该应用程序已经占用了 2GB 空间。问题是,一旦完成(搜索),内存仍未释放- 所以我想这表明存在问题。
那么,有什么想法吗?
请让我知道,以防您需要了解有关实施的任何其他信息。
提示:
FOREACH
只是向量迭代器的宏- for 向量附加来自
+=
Boost - 粗体中的所有内容都是一个宏,但就内存开销而言,它们都没有做任何密集的事情(所以我决定省略它们)
- 没有实现任何析构函数