Author: Stefano Gemma
Date: 12:54:57 08/24/00
Go up one level in this thread
On August 24, 2000 at 15:00:23, leonid wrote:
>On August 24, 2000 at 02:26:22, Stefano Gemma wrote:
>>I don't think that this is impossible. On a Pentium 450 MHz machine, my new
>>assembly engine can reach about 12 million positions per second. But this
>>version of the engine has the simplest possible evaluation function and it is
>>very very weak. A programmer better than me and with a faster hardware can easly
>>reach the numbers you've said, using more complex evaluation.
>Never mind how weak your engin is but 12 millions positions per second sound to
>me as too good to be real. But if you have them, you have bright future! Do you
>have some visible NPS counter in your program?
The new engine is not yet released, but the two previous ones are. If you take a
look at the Drago sources, you can see if i'm right or maybe i'm wrong with the
moves counter. But Drago was the first one. The second engine, Raffaela, was
faster than Drago, not just because of the 32 bit. She reaches about 4/5 million
moves generated per second. But this is not so amazing as it can seeems. This
numbers can easly been reached if you use a small evaluation function. The
resulting program is faster than any other one... but it play weaker. As i often
said: my programs generates millions of... bad moves per second ;-))))
>After what some programmers said here, number of moves (not even positions) that
>their programs were able to generate was around 1.8 millions for 466Mhz
>computer. My program is likely to confirm this indirectly.
I confirm this number myself. An experimental engine i had wrote in C++ have
about the same performance. I'm now sure (imho) that a normal assembly program
can be ten time faster than a good C/C++ one. But debugging and developing is
slower and harder.
> 12 million are very
>far from those numbers. When it is said that it is positions/second, even more
>so. If you could say what kind of moves your program generate, it will be good.
The counting includes all legal moves (captures and not captures) plus those who
leave the King in chess (discovered in the next ply, obviously).
>Brifly about your evealuation, if you can. After your like, you can respond here
>or send your message to my e-mail address.
The evaluation take care just about of piece values and position.
>Please mention what language you used (NASM, MASM...) and for what system.
I compile asm sources on Borland C++ Builder environment, but i don't use
Borland features. The kind of assembler is not important. All the proget was
started a lot of year ago, on a z80 cpu.. then 6510 and finally 80x86.
The moves generation (in the new engine) is based on a simple chess-board
rapresentation: 16x16 (equal to 12x12, but simpler to program). I don't use
bitboards or any other trick. I just use a lot of macro, instead of procedures
calling. They are similar to inline C++ function, in some way. Drago sources are
an explanation of this. The chessboard contains piece indexes (or pointers) and
values. An array of pieces contains the kind, position and some flag for any
piece. Nothing special, many other program do the same. The main algorithm is a
"reinvented" alpha-beta that i have called alfa-gemma ;-). I dont' know if in
english sound the same... in Italy we say "reinventare l'acqua calda" ("to
re-invent hot water"?). The only good think of my version is that i don't need
to recursly call alfa-beta. I just jump forward and back. But i have to take
care of an array of nodes... and the array of nodes looks very similar to a
stack. The alfa and beta values are stored in that stack. Considering all the
facts, alfa-gemma seems to be just a jumping version of alfa-beta... maybe i
should call it "jumping jam flash" ;-)))).
I've said that i use macro, to generate moves. This avoid a couple of call/ret
assembly instructions. To be fast, i have optimized the MUOVI macro (Muovi=Make
Move) so that now it is just 12 assembly istructions in lenght (plus 2
extra-istruction for pawns). The Drago version was this one (see gsmacro.mac):
MUOVI_RE macro scacco_mr, prima
LOCAL @mrRight, @mrLeft, @mrUp, @mrDown, @mrUpRight, @mrDownLeft, @mrDownRight,
@mrUpLeft, @mrEnd
@mrRight:
inc al
CHECKXY_PUSH @mrLeft, scacco_mr
SWITCH_ARROCCO prima, meno
@mrLeft:
add al, 0feh
CHECKXY_PUSH @mrUp, scacco_mr
SWITCH_ARROCCO prima, meno
@mrUp:
This make the program unreadable, but fast.
The new engine, use this moves generation macros:
;--------------------------------------------
MUOVIRIGA macro delta
local @prossimariga
MUOVI delta*1,@prossimariga,1,0,0
MUOVI delta*2,@prossimariga,1,0,0
MUOVI delta*3,@prossimariga,1,0,0
MUOVI delta*4,@prossimariga,1,0,0
MUOVI delta*5,@prossimariga,1,0,0
MUOVI delta*6,@prossimariga,1,0,0
MUOVI delta*7,@prossimariga,1,0,0
@prossimariga:
endm
;--------------------------------------------
MUOVI8 macro d1,d2,d3,d4
local @p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8
MUOVI d1,@p1,0,0,0
@p1:
MUOVI d2,@p2,0,0,0
@p2:
MUOVI d3,@p3,0,0,0
@p3:
MUOVI d4,@p4,0,0,0
@p4:
MUOVI -d1,@p5,0,0,0
@p5:
MUOVI -d2,@p6,0,0,0
@p6:
MUOVI -d3,@p7,0,0,0
@p7:
MUOVI -d4,@p8,0,0,0
@p8:
endm
;--------------------------------------------
MUOVIRIGA_AB macro delta
MUOVIRIGA delta
MUOVIRIGA -delta
endm
;--------------------------------------------
MuoviVuota proc
ret
MuoviVuota endp
;--------------------------------------------
MuoviRe proc
MUOVI8 00fh,010h,011h,001h
ret
MuoviRe endp
;--------------------------------------------
MuoviDonna proc
MUOVIRIGA_AB 001h
MUOVIRIGA_AB 010h
MUOVIRIGA_AB 011h
MUOVIRIGA_AB 00fh
ret
MuoviDonna endp
;--------------------------------------------
MuoviTorre proc
MUOVIRIGA_AB 001h
MUOVIRIGA_AB 010h
ret
MuoviTorre endp
;--------------------------------------------
MuoviAlfiere proc
MUOVIRIGA_AB 011h
MUOVIRIGA_AB 00fh
ret
MuoviAlfiere endp
;--------------------------------------------
MuoviCavallo proc
MUOVI8 00eh,012h,01fh,021h
ret
MuoviCavallo endp
;--------------------------------------------
MuoviPedoneB proc
MUOVI -010h,mpb_nodidue,0,1,1
cmp esi,offset FinePedoniB ; ## da ottimizzare
jl mpb_nodidue
MUOVI -020h,mpb_nodidue,0,1,1
mpb_nodidue:
MUOVI -00Fh,mpb_nosinistra,0,1,0
mpb_nosinistra:
MUOVI -011h,mpb_nodestra,0,1,0
mpb_nodestra:
ret
MuoviPedoneB endp
;--------------------------------------------
MuoviPedoneN proc
MUOVI 010h,mpn_nodidue,0,1,1
cmp esi,offset FinePedoniN ; ## da ottimizzare
jge mpn_nodidue
MUOVI 020h,mpn_nodidue,0,1,1
mpn_nodidue:
MUOVI 00Fh,mpn_nosinistra,0,1,0
mpn_nosinistra:
MUOVI 011h,mpn_nodestra,0,1,0
mpn_nodestra:
ret
MuoviPedoneN endp
;--------------------------------------------
(From italian to english: sinistra=left, destra=right,Torre=rook, Donna=queen,
Alfiere=bishop, Re=King, Pedone=pawn, nodidue=no di due=cannot moves of two
square,PedoneB=white pawn,PedoneN=black pawn,muovi=move, ecc.)
;--------------------------------------------
The programs is more readable than the old 16 bit version. All the job is done
in the MUOVI macro. This is the macro that is just 12 assembly istructions in
lenght. I'm working to tear away one ore two of this 12 istructions. I optimize
by hand for Pentium pipes, with the help of Quantasm PentOpt. I' even working on
a genethical version, but is not more than a joke, for now (is the version with
the C++ engine of "just" 2 million moves per second).
It's only rock & roll... but i like it! ;-)))))
Ciao!!!
But still the program is playing not so good as i wish.
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.