Skip to content

Commit

Permalink
Additional tidy up in timeman.cpp
Browse files Browse the repository at this point in the history
Fixed some comments and moved/renamed some
variables.

No functional change.
  • Loading branch information
mcostalba committed Dec 30, 2014
1 parent 6933f05 commit 2416242
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/search.cpp
Expand Up @@ -193,7 +193,7 @@ template uint64_t Search::perft<true>(Position& pos, Depth depth);

void Search::think() {

TimeMgr.init(Limits, RootPos.game_ply(), RootPos.side_to_move());
TimeMgr.init(Limits, RootPos.side_to_move(), RootPos.game_ply());

int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
DrawValue[ RootPos.side_to_move()] = VALUE_DRAW - Value(contempt);
Expand Down
70 changes: 35 additions & 35 deletions src/timeman.cpp
Expand Up @@ -33,10 +33,6 @@ namespace {
const double MaxRatio = 7.0; // When in trouble, we can step over reserved time with this ratio
const double StealRatio = 0.33; // However we must not steal time from remaining moves over this ratio

const double xscale = 9.3;
const double xshift = 59.8;
const double skewfactor = 0.172;


// move_importance() is a skew-logistic function based on naive statistical
// analysis of "how many games are still undecided after n half-moves". Game
Expand All @@ -45,72 +41,76 @@ namespace {

double move_importance(int ply) {

return pow((1 + exp((ply - xshift) / xscale)), -skewfactor) + DBL_MIN; // Ensure non-zero
const double XScale = 9.3;
const double XShift = 59.8;
const double Skew = 0.172;

return pow((1 + exp((ply - XShift) / XScale)), -Skew) + DBL_MIN; // Ensure non-zero
}

template<TimeType T>
int remaining(int myTime, int movesToGo, int currentPly, int slowMover)
int remaining(int myTime, int movesToGo, int ply, int slowMover)
{
const double TMaxRatio = (T == OptimumTime ? 1 : MaxRatio);
const double TStealRatio = (T == OptimumTime ? 0 : StealRatio);

double thisMoveImportance = (move_importance(currentPly) * slowMover) / 100;
double moveImportance = (move_importance(ply) * slowMover) / 100;
double otherMovesImportance = 0;

for (int i = 1; i < movesToGo; ++i)
otherMovesImportance += move_importance(currentPly + 2 * i);
otherMovesImportance += move_importance(ply + 2 * i);

double ratio1 = (TMaxRatio * thisMoveImportance) / (TMaxRatio * thisMoveImportance + otherMovesImportance);
double ratio2 = (thisMoveImportance + TStealRatio * otherMovesImportance) / (thisMoveImportance + otherMovesImportance);
double ratio1 = (TMaxRatio * moveImportance) / (TMaxRatio * moveImportance + otherMovesImportance);
double ratio2 = (moveImportance + TStealRatio * otherMovesImportance) / (moveImportance + otherMovesImportance);

return int(myTime * std::min(ratio1, ratio2));
return myTime * std::min(ratio1, ratio2);
}

} // namespace


void TimeManager::init(const Search::LimitsType& limits, int currentPly, Color us)
{
/* We support four different kinds of time controls:
increment == 0 && movesToGo == 0 means: x basetime [sudden death!]
increment == 0 && movesToGo != 0 means: x moves in y minutes
increment > 0 && movesToGo == 0 means: x basetime + z increment
increment > 0 && movesToGo != 0 means: x moves in y minutes + z increment
*/

int hypMTG, hypMyTime, t1, t2;
/// init() is called at the beginning of the search and calculates the allowed
/// thinking time out of the time control and current game ply. We support four
/// different kinds of time controls, passed in 'limits':
///
/// inc == 0 && movestogo == 0 means: x basetime [sudden death!]
/// inc == 0 && movestogo != 0 means: x moves in y minutes
/// inc > 0 && movestogo == 0 means: x basetime + z increment
/// inc > 0 && movestogo != 0 means: x moves in y minutes + z increment

// Read uci parameters
int moveOverhead = Options["Move Overhead"];
void TimeManager::init(const Search::LimitsType& limits, Color us, int ply)
{
int minThinkingTime = Options["Minimum Thinking Time"];
int moveOverhead = Options["Move Overhead"];
int slowMover = Options["Slow Mover"];

// Initialize unstablePvFactor to 1 and search times to maximum values
unstablePvFactor = 1;
optimumSearchTime = maximumSearchTime = std::max(limits.time[us], minThinkingTime);

// We calculate optimum time usage for different hypothetical "moves to go"-values and choose the
// minimum of calculated search time values. Usually the greatest hypMTG gives the minimum values.
for (hypMTG = 1; hypMTG <= (limits.movestogo ? std::min(limits.movestogo, MoveHorizon) : MoveHorizon); ++hypMTG)
const int MaxMTG = limits.movestogo ? std::min(limits.movestogo, MoveHorizon) : MoveHorizon;

// We calculate optimum time usage for different hypothetical "moves to go"-values
// and choose the minimum of calculated search time values. Usually the greatest
// hypMTG gives the minimum values.
for (int hypMTG = 1; hypMTG <= MaxMTG; ++hypMTG)
{
// Calculate thinking time for hypothetical "moves to go"-value
hypMyTime = limits.time[us]
+ limits.inc[us] * (hypMTG - 1)
- moveOverhead * (2 + std::min(hypMTG, 40));
int hypMyTime = limits.time[us]
+ limits.inc[us] * (hypMTG - 1)
- moveOverhead * (2 + std::min(hypMTG, 40));

hypMyTime = std::max(hypMyTime, 0);

t1 = minThinkingTime + remaining<OptimumTime>(hypMyTime, hypMTG, currentPly, slowMover);
t2 = minThinkingTime + remaining<MaxTime>(hypMyTime, hypMTG, currentPly, slowMover);
int t1 = minThinkingTime + remaining<OptimumTime>(hypMyTime, hypMTG, ply, slowMover);
int t2 = minThinkingTime + remaining<MaxTime >(hypMyTime, hypMTG, ply, slowMover);

optimumSearchTime = std::min(optimumSearchTime, t1);
maximumSearchTime = std::min(maximumSearchTime, t2);
optimumSearchTime = std::min(t1, optimumSearchTime);
maximumSearchTime = std::min(t2, maximumSearchTime);
}

if (Options["Ponder"])
optimumSearchTime += optimumSearchTime / 4;

// Make sure that maxSearchTime is not over absoluteMaxSearchTime
optimumSearchTime = std::min(optimumSearchTime, maximumSearchTime);
}
2 changes: 1 addition & 1 deletion src/timeman.h
Expand Up @@ -25,7 +25,7 @@

class TimeManager {
public:
void init(const Search::LimitsType& limits, int currentPly, Color us);
void init(const Search::LimitsType& limits, Color us, int ply);
void pv_instability(double bestMoveChanges) { unstablePvFactor = 1 + bestMoveChanges; }
int available_time() const { return int(optimumSearchTime * unstablePvFactor * 0.71); }
int maximum_time() const { return maximumSearchTime; }
Expand Down

3 comments on commit 2416242

@irulats
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm only a C++ learner, so please bear with me. In line 66 of timeman.cpp you removed the int after return even though MyTime has been defined as int type and ratio 1&2 as double. I expected you to change it to static_cast . I know it still works since we know better.
Am I way off base here?

@lucasart
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  • writing int(x), or static_cast<int>(x) is the same thing. The latter is particularly ugly, so we prefer the former... except in the syzygy code, where, for some unknown reason, Gary decided to use static_cast<T>. But the syzygy code is ugly anyway, so...
  • int cast is implicit here, because the return value of the function is int (the compiler knows that). So you can add an int cast to be pedantic, but it's not necessary.

@irulats
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, fair enough. Thanks for the explanation. I'm probably too pedantic at the best of times. I presume they all compile the same at any rate.

Please sign in to comment.