Computer Chess Club Archives


Search

Terms

Messages

Subject: much better makefile for recent crafties (long post)

Author: Michel Langeveld

Date: 04:33:58 11/13/99


I tried it with Crafty 17.1 but it should work with older version also.
It produces the a very crafty which is even a slightly faster then the crafty on
ftp.cis.uab.edu/.../v17/wcrafty.17_1.exe. Yes, finally I made it :-) !

The basic tricks were not to combine to 2 source-codes but 1 large source-code.
And use the right optimization options. I have included in comment a short
description of an option.

I have included also a modified version of bench.c so know it produces a more
accurate time because it displays also hundreds of a second and calculates the
nps correctly (It was rounded far too early).

If you want a very quick crafty then add "__forceinline" before "int evaluate("
in evaluate.c!

build with Visual Studio 6.0 Service Pack 3 and with the command:
"nmake -f makefile.nt wcraftyx"

If you improve something then let me know.

Please be free to contact me!

Kind regards,

Michel Langeveld (rudolf@stad.dsl.nl)

---------------------- CUT HERE and save as makefile.nt ----------------------

#########################################################################
# Makefile version 4 for Crafty 17.01
# Crafty v16.x makefile for Windows NT Intel
# Written by Jason Deines (jdeines@mindspring.com) April 1998
# Version modified by Gregor Overney (gregor_overney@hp.com) Nov 1998
# Version modified by Peter Karrer (pkarrer@active.ch) Dec 1998
# Version modified by Gregor Overney (gregor_overney@hp.com) Sep 1999
# Version modified by Michel Langeveld (rudolf@stad.dsl.nl) Nov 1999
#
# This makefile is designed to be used from the command line with
# Microsoft's nmake.  Either rename this # file to "Makefile" or name it
# explicitly when invoking nmake:
#     nmake -f Makefile.nt
#
# The makefile is set up for Microsoft Visual C++ 6.0 Intel.
# Visual Studio - Service Pack 3 is recommended
#
# The default target produces a file called "wcrafty.exe".  This compiles
# all the .c files separately, producing individual .obj files, which are
# then linked to create the executable.
#
# You can also specify a target called "wcraftyx".  This creates a file
# called "wcraftyx.exe" by combining all of the .c files into two large .c
# files before the compile step.
#
# The large files generally provides more optimization possibilities for
# the compiler, and usually results in slightly faster code.  To try it,
# type "nmake -f makefile.nt wcraftyx" instead of just "nmake -f makefile.nt".
# The .c files x1.c and x2.c will be created if needed and built automatically.
#########################################################################

# Build target is defined here.
TARGET   = NT_i386

# Command-line compiler and linker invocation commands:
CC       = cl
LD       = link

# Base compiler flags needed for build:
BFLAGS = /D_CONSOLE /DWIN32

# Compiler flags:
# /Ox    optionpack to optimize for speed (/Ob2gity)

# /O2    optimize for speed
# /G5    target Pentium (but will run on all x86 architectures)
# /G6    target Pentium Pro (but will run on all x86 architectures)
# /Gr    fastcall calling convention
# /Oa    assume no aliasing (no good for VC 6 without SP3)
#        According to Eugene Namilov this option produces incorrect code
#        with egtb.cpp. Don't use it!
# /Ob2   inline any function calls suitable
# /Og    perform global supexpression
# /Oi    Enable intrinsics
# /Ol    loop optimization
# /Oo    peephole optimization
# /Ot    Favor fast code
# /Oy    Frame pointer omision
# /Gs    controls Stack Checking Calls
#
# For debugging use these flags instead:
# /Od    perform no optimization
# /Zi    produces a program database with type- and symbolic information
#
# CFLAGS  = /Od /Zi
# LDFLAGS  = /DEBUG /DEBUGTYPE:CV
#

#CFLAGS   = /Od /Zi
CFLAGS   = /O2 /Oy /Ot /Ob2 /Oi /G6 /Gr /Og

# Linker flags, normally not needed except for debug builds:
LDFLAGS  =
#LDFLAGS  = /DEBUG /DEBUGTYPE:CV

# See the default crafty makefile for a description of the options below.
# With VC++, defines like COMPACT_ATTACKS, etc, makes the code slower, so
# those # options are disabled by default.
#
# FAST is normally not defined so that hash statistics are reported --
# for the fastest possible executable, define FAST below.
#
# for 6 piece EGTB support, add /DEGTB6.
#
# Michel Langeveld: According to my experience it seems to be /DFAST produces
# an slower exe. Although it seems strange it's true for me.

#COPTS    = /DFAST /DEGTB6
#COPTS = /DQUICKBENCH

# For an SMP build use/add the following build options.
# NT_INTEREX is defined if you want to use the built-in InterlockedExchange()
# function for thread resource locking, instead of the inline asm routine.
# (This shouldn't be needed, at least on Intel.)
# /MT is a compiler flag needed for multithreaded builds.

#COPTS    = /MT /DSMP /DCPUS=4 /DNT_INTEREX
#COPTS    = /MT /DSMP /DCPUS=2

# If you are using any external assembler routines, put the name of the
# object code file(s) here.  Any such files will need to be generated
# separately -- there is no assembler step defined in the makefile.

asmobjs  =

# To enable assembly optimizations in x86.c and vcinline.h, use /DVC_INLINE_ASM.

AOPTS    = /DVC_INLINE_ASM

ALLOPTS  = $(COPTS) $(AOPTS) /D$(TARGET)

cobjs    = analyze.obj annotate.obj attacks.obj bench.obj book.obj boolean.obj \
           data.obj drawn.obj edit.obj enprise.obj epd.obj \
           epdglue.obj evaluate.obj evtest.obj hash.obj history.obj init.obj \
           input.obj interupt.obj iterate.obj learn.obj make.obj main.obj \
           movgen.obj next.obj nexte.obj nextr.obj output.obj \
           phase.obj ponder.obj preeval.obj quiesce.obj repeat.obj resign.obj \
           root.obj search.obj searchmp.obj searchr.obj setboard.obj swap.obj \
           test.obj thread.obj time.obj unmake.obj utility.obj valid.obj \
           validate.obj probe.obj x86.obj

xcobjs   = x1.obj
#x2.obj

allobjs  = $(cobjs) $(asmobjs) egtb.obj

xallobjs = $(xcobjs) $(asmobjs) egtb.obj

includes = chess.h data.h epd.h epddefs.h epdglue.h evaluate.h vcinline.h
makefile.nt

wcrafty  : $(allobjs)
           $(LD) $(LDFLAGS) $(allobjs) /out:wcrafty.exe

wcraftyx : $(xallobjs)
           $(LD) $(LDFLAGS) $(xallobjs) /out:wcraftyx.exe
           wcraftyx.exe

$(cobjs) : $(includes)

.c.obj   :
           $(CC) $(BFLAGS) $(CFLAGS) $(ALLOPTS) /c $*.c

.cpp.obj :
           $(CC) $(BFLAGS) $(CFLAGS) $(ALLOPTS) /c $*.cpp

$(xcobjs): $(includes)

x1.c:      searchr.c search.c repeat.c next.c nextr.c history.c nexte.c \
           quiesce.c evaluate.c movgen.c make.c unmake.c attacks.c swap.c \
           boolean.c utility.c valid.c searchmp.c thread.c x86.c enprise.c \
           book.c data.c drawn.c edit.c epd.c epdglue.c init.c \
           input.c interupt.c iterate.c main.c output.c phase.c \
           ponder.c preeval.c resign.c root.c learn.c setboard.c test.c time.c \
           validate.c annotate.c analyze.c evtest.c bench.c hash.c probe.c
           copy /b x86.c+boolean.c+swap.c+attacks.c+evaluate.c+make.c+\
           unmake.c+movgen.c+quiesce.c+search.c+next.c+searchr.c+repeat.c+\
           nextr.c+history.c+nexte.c+utility.c+valid.c+searchmp.c+\
           thread.c+enprise.c+book.c+data.c+drawn.c+edit.c+epd.c+epdglue.c+\
           init.c+input.c+interupt.c+iterate.c+main.c+output.c+\
           phase.c+ponder.c+preeval.c+resign.c+root.c+learn.c+setboard.c+\
           test.c+time.c+validate.c+annotate.c+analyze.c+evtest.c+bench.c+\
           hash.c+probe.c x1.c

clean:
	   del /q $(cobjs)
	   del /q egtb.obj
	   del /q $(xcobjs)
	   del /q log.*
	   del /q game.**
	   del /q *.bak
	   del /q x1.c
#           del /q x2.c

---------------------- CUT HERE and save as bench.c ----------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chess.h"
#include "data.h"

/* last modified 8/6/99 */
/*
********************************************************************************
*                                                                              *
*   Bench() runs a simple six-position benchmark to gauge crafty's             *
*   performance.  The test positons are hard-coded, and the benchmark is       *
*   calculated much like it would with an external "test" file.  The test      *
*   is a mix of opening, middlegame, and endgame positions, with both tactical *
*   and positional aspects.  (For those interested, the positions chosen are   *
*   Bratko-Kopec 2, 4, 8, 12, 22 and 23.)  This test is a speed measure only;  *
*   the actual solutions to the positions are ignored.                         *
*                                                                              *
********************************************************************************
*/

void Bench(void) {
  double nodes=0.0;
  int old_do, old_st, old_sd, total_time_used;
  TREE * const tree=local[0];

  test_mode=1;
  total_time_used=0;
  old_st=search_time_limit;  /* save old time limit and display settings */
  old_sd=search_depth;
  old_do=display_options;
  search_time_limit=90000;   /* maximum of 15 minutes per position */
  display_options=1;         /* turn off display while running benchmark */

  if (book_file) {
    fclose(book_file);
    fclose(books_file);
    book_file=0;
    books_file=0;
  }

  Print(4095, "Running benchmark. . .\n");

  printf(".");
  fflush(stdout);
  strcpy(args[0],"3r1k2/4npp1/1ppr3p/p6P/P2PPPP1/1NR5/5K2/2R5");
  strcpy(args[1],"w");
  SetBoard(2,args,0);
  search_depth=11;

  InitializeHashTables();
  last_pv.pathd=0;
  largest_positional_score=100;
  thinking=1;
  tree->position[1]=tree->position[0];
  (void) Iterate(wtm,think,0);
  thinking=0;
  nodes+=(float)(tree->nodes_searched);
  total_time_used+=(program_end_time-program_start_time);
  printf(".");
  fflush(stdout);

#ifndef QUICKBENCH
  strcpy(args[0],"rnbqkb1r/p3pppp/1p6/2ppP3/3N4/2P5/PPP1QPPP/R1B1KB1R");
  strcpy(args[1],"w");
  strcpy(args[2],"KQkq");
  SetBoard(3,args,0);
  search_depth=11;

  InitializeHashTables();
  last_pv.pathd=0;
  largest_positional_score=100;
  thinking=1;
  tree->position[1]=tree->position[0];
  (void) Iterate(wtm,think,0);
  thinking=0;
  nodes+=(float)(tree->nodes_searched);
  total_time_used+=(program_end_time-program_start_time);
  printf(".");
  fflush(stdout);

  strcpy(args[0],"4b3/p3kp2/6p1/3pP2p/2pP1P2/4K1P1/P3N2P/8");
  strcpy(args[1],"w");
  SetBoard(2,args,0);
  search_depth=14;

  InitializeHashTables();
  last_pv.pathd=0;
  largest_positional_score=100;
  thinking=1;
  tree->position[1]=tree->position[0];
  (void) Iterate(wtm,think,0);
  thinking=0;
  nodes+=(float)(tree->nodes_searched);
  total_time_used+=(program_end_time-program_start_time);
  printf(".");
  fflush(stdout);

  strcpy(args[0],"r3r1k1/ppqb1ppp/8/4p1NQ/8/2P5/PP3PPP/R3R1K1");
  strcpy(args[1],"b");
  SetBoard(2,args,0);
  search_depth=11;

  InitializeHashTables();
  last_pv.pathd=0;
  largest_positional_score=100;
  thinking=1;
  tree->position[1]=tree->position[0];
  (void) Iterate(wtm,think,0);
  thinking=0;
  nodes+=(float)(tree->nodes_searched);
  total_time_used+=(program_end_time-program_start_time);
  printf(".");
  fflush(stdout);

  strcpy(args[0],"2r2rk1/1bqnbpp1/1p1ppn1p/pP6/N1P1P3/P2B1N1P/1B2QPP1/R2R2K1");
  strcpy(args[1],"b");
  SetBoard(2,args,0);
  search_depth=12;

  InitializeHashTables();
  last_pv.pathd=0;
  largest_positional_score=100;
  thinking=1;
  tree->position[1]=tree->position[0];
  (void) Iterate(wtm,think,0);
  thinking=0;
  nodes+=(float)(tree->nodes_searched);
  total_time_used+=(program_end_time-program_start_time);
  printf(".");
  fflush(stdout);

  strcpy(args[0],"r1bqk2r/pp2bppp/2p5/3pP3/P2Q1P2/2N1B3/1PP3PP/R4RK1");
  strcpy(args[1],"b");
  strcpy(args[2],"kq");
  SetBoard(3,args,0);
  search_depth=11;

  InitializeHashTables();
  last_pv.pathd=0;
  largest_positional_score=100;
  thinking=1;
  tree->position[1]=tree->position[0];
  (void) Iterate(wtm,think,0);
  thinking=0;
  nodes+=(float)(tree->nodes_searched);
  total_time_used+=(program_end_time-program_start_time);
#endif

  printf("\n");
  Print(4095,"Total nodes: %d\n", (int)nodes);
  Print(4095,"Raw nodes per second: %d\n", (int)(nodes / (total_time_used /
100.0)));
  Print(4095,"Total elapsed time: %.2f\n", (total_time_used / 100.0));
  Print(4095,"SMP time-to-ply measurement: %.2f\n", (640.0 / (total_time_used /
100.0)));
  input_stream=stdin;
  early_exit=99;
  test_mode=0;

  display_options=old_do;    /* reset old values and restart game */
  search_time_limit=old_st;
  search_depth=old_sd;
  NewGame(0);
}



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.