Home › Forum › Programmazione › Il ritorno di Drago
Questo argomento contiene 17 risposte, ha 2 partecipanti, ed è stato aggiornato da stegemma 1 mese, 3 settimane fa.
-
AutoreArticoli
-
20/07/2018 alle 11:20 #12187
“Drago” è un nome storico, per il nostro Gruppo… perché non recuperarlo? Le premesse ci sono tutte: engine in assembly (in stile Drago e Raffaela) con istruzioni a 64 bit (in stile Freccia) e l’interfaccia xBoard/genetica di Satana/Sabrina ma con un’ottica più moderna, sfruttando perfino i registri a 256 bit YMM.
Ritornare al nome del mio primo programma, conosciuto fin dai tempi delle BBS, rappresenta il completamento di un percorso di sperimentazione e sviluppo; ecco perché all’IGT 2018 parteciperò con Drago!
Le premesse sono queste, con il perft di Sabrina confrontato con quello di Drago, che non è nemmeno ottimizzato al massimo (ma non fornisce ancora i valori esatti):
Sabrina - perft 7: Nodes: 3195901860, Time: 62163 ms, Nodes/s: 51410814 Drago - perft 7: #3208932083: 39.035s 82204428 nodes/sec
Il nuovo Drago resterà privato ma potrete sbirciare nei sorgenti all’IGT.
22/07/2018 alle 15:58 #12189Il percorso per sviluppare un motore è ormai consolidato:
– generatore mosse nudo e crudo, senza mosse speciali
– un abbozzo di perft
– qualche funzione di debug, per visualizzare almeno la scacchiera (eventualmente anche le mosse giocate)
– test con Re + un solo pezzo o soli pedoni
– test dalla posizione iniziale
– implementazione di en-passant
– test fino a perft 6 dalla posizione iniziale standard
– implementazione della promozione
– test con promozioni con o senza prese (a DTAC)
– implementazione dell’arrocco
– perft 7 dalla posizione iniziale
– varie posizioni di test
– funzione di valutazione minima (solo il valore dei pezzi)
– implementazione di alphabeta/alfagemma
– test poi test poi test poi test
– espansione della funzione di valutazione
– test poi test poi testSembra tanta roba ma sono le prove ed il debug a portar via la maggior parte del tempo, almeno al livello dei miei programmi attuali.
Sono arrivato all’en-passant… da domani sera si passa all’arrocco.
Ecco lo stato dell’arte, che è ancora ampiamente migliorabile ma va già benissimo così:
\drago 1 #20: 0.002s 6666 moves/sec #20: 0.002s 6666 leaves/sec \drago 2 #420: 0.005s 70000 moves/sec #400: 0.006s 57142 leaves/sec \drago 3 #9322: 0.004s 1864400 moves/sec #8902: 0.005s 1483666 leaves/sec \drago 4 #207064: 0.007s 25883000 moves/sec #197281: 0.008s 21920111 leaves/sec \drago 5 #5087587: 0.058s 86230288 moves/sec #4865609: 0.059s 81093483 leaves/sec \drago 6 #125049325: 1.289s 96937461 moves/sec #119060324: 1.29s 92223333 leaves/sec \drago 7 #3346841488: 35.905s 93211203 moves/sec #3195018407: 35.906s 88980377 leaves/sec
NB: come da scaletta, il perft 7 è incompleto perché manca l’arrocco.
23/07/2018 alle 22:41 #12195Queste sì, che sono soddisfazioni!
\drago 7 #3347724941: 44.825s 74682660 moves/sec #3195901860: 44.827s 71292537 leaves/sec perft 7 Nodes: 3195901860, Time: 61945 ms, Nodes/s: 51591738
24/07/2018 alle 10:12 #12196Dulcis in fundo, un confronto relativo al solo arrocco (comprese mosse di Re e Torre):
verifica arrocco: setboard r3k2r/8/8/8/8/8/8/R3K2R w KQkq perft 1: Nodes: 26, Time: 0 ms, Nodes/s: 26000 perft 2: Nodes: 568, Time: 0 ms, Nodes/s: 568000 perft 3: Nodes: 13744, Time: 0 ms, Nodes/s: 13744000 perft 4: Nodes: 314346, Time: 6 ms, Nodes/s: 44906571 perft 5: Nodes: 7594526, Time: 146 ms, Nodes/s: 51663442 perft 6: Nodes: 179862938, Time: 3429 ms, Nodes/s: 52438174 perft 7: Nodes: 4408318687, Time: 82131 ms, Nodes/s: 53673582 \drago 1: #26: 0.001s 13000 moves/sec #26: 0.002s 8666 leaves/sec \drago 2 #631: 0s 631000 moves/sec #568: 0.002s 189333 leaves/sec \drago 3 #15445: 0.001s 7722500 moves/sec #13744: 0.002s 4581333 leaves/sec \drago 4 #366083: 0.005s 61013833 moves/sec #314346: 0.006s 44906571 leaves/sec \drago 5 #8862308: 0.107s 82058407 moves/sec #7594526: 0.108s 69674550 leaves/sec \drago 6 #212637123: 2.754s 77182258 moves/sec #179862938: 2.755s 65262314 leaves/sec \drago 7 #5220219190: 62.571s 83427398 moves/sec #4408318687: 62.573s 70449686 leaves/sec
Qui si nota che il perft legato all’arrocco è comunque più veloce nella versione assembly che in quella C++, nonostante il controllo dello scacco sia ancora del tutto inefficiente. La versione assembly risulta impiegare circa il 25% di tempo in meno della versione C++, per il perft 7 in questa posizione.
Questo invece è il confronto completo aggiornato alla radice:
new \ # rnbqkbnr pppppppp ........ ........ ........ ........ PPPPPPPP RNBQKBNR # white value: 0.00 FEN: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - # perft 1: Nodes: 20, Time: 0 ms, Nodes/s: 20000 perft 2: Nodes: 400, Time: 0 ms, Nodes/s: 400000 perft 3: Nodes: 8902, Time: 0 ms, Nodes/s: 8902000 perft 4: Nodes: 197281, Time: 4 ms, Nodes/s: 39456200 perft 5: Nodes: 4865609, Time: 95 ms, Nodes/s: 50683427 perft 6: Nodes: 119060324, Time: 2523 ms, Nodes/s: 47171285 perft 7: Nodes: 3195901860, Time: 61945 ms, Nodes/s: 51591738 \drago 1 #20: 0.001s 10000 moves/sec #20: 0.002s 6666 leaves/sec \drago 2 #420: 0.001s 210000 moves/sec #400: 0.002s 133333 leaves/sec \drago 3 #9322: 0.001s 4661000 moves/sec #8902: 0.002s 2967333 leaves/sec \drago 4 #207064: 0.003s 51766000 moves/sec #197281: 0.005s 32880166 leaves/sec \drago 5 #5087587: 0.065s 77084651 moves/sec #4865609: 0.067s 71553073 leaves/sec \drago 6 #125049325: 1.637s 76342689 moves/sec #119060324: 1.638s 72642052 leaves/sec \drago 7 #3347724941: 43.417s 77104540 moves/sec #3195901860: 43.418s 73606067 leaves/sec
Anche qui, al livello 7 abbiamo 43″ (assembly) contro 61″ (C++).
Aggiungendo la funzione di valutazione, la cache ecc., i nodi/s caleranno drasticamente, ovviamente.
NB: single-core, senza cache e con esecuzione di tutte le mosse anche nei nodi foglia (compreso calcolo del valore dei pezzi eventualmente catturati)
01/08/2018 alle 22:34 #12214Rosicchiando qui e là:
\drago 7 1/1 rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 20 2 400 3 8902 4 197281 5 4865609 6 119060324 7 3195901860 3195901860 [TIME_MS=42529] [NPS=75146414] [STATUS=OK]
Sono passato da 73 a 75 Mn/s ma si può fare ancora meglio.
03/08/2018 alle 06:43 #12215E mentre verifichi la funzione di evasione dallo scacco, scopri che i programmi perdono il loro tempo ad analizzare posizioni come questa:
[PGN]
[FEN “rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -“]
[/PGN]Che poi, essendo un matto, fa piantare il programma, perché il bianco non ha mosse legali (grazie alla funzione di evasione stessa).
11/08/2018 alle 16:35 #12235Tra le tante cose “folli” che sto facendo, c’è anche un programma che converte i sorgenti in assembly di Drago in sorgenti in c++; questo servirà per rendere portabile la parte assembly, così che sia ottimizzata sotto Windows e almeno funzionante sotto Mac/Linux. Poi potrei scoprire che il compilatore c++ ottimizzerà il mio sorgente ex-assembly in modo molto migliore di come l’ho scritto in origine… e sarebbe veramente “triste”! 😉
Questo è un piccolo assaggio di quello che fa il programmino “folle”:
Sorgente assembly:
DebugSlide proc push rax call DebugBits mov rax, r12 call DebugBits pop rax ret DebugSlide endp
Conversione in c++:
void DebugSlide() { Stack.Push(rax); DebugBits(); rax = r12; DebugBits(); rax = Stack.Top(); Stack.Pop(); return; } // DebugSlide
29/08/2018 alle 15:32 #12245Altra “rosicchiata” di un secondo abbondante:
\drago perft 7 # 1 20 # 2 400 # 3 8902 # 4 197281 # 5 4865609 # 6 119060324 # 7 3195901860 Nodes: 3195901860, Time: 41093 ms, Nodes/s: 77770522
Più importante il guadagno ottenuto in alcune posizioni:
setboard r3k2r/8/8/8/8/8/8/R3K2R w KQkq # Sabrina perft 7: Nodes: 4408318687, Time: 82131 ms, Nodes/s: 53673582 # Drago luglio 2018: #4408318687: 62.573s 70449686 leaves/sec # Drago attuale: perft 7 # 1 26 # 2 568 # 3 13744 # 4 314346 # 5 7594526 # 6 179862938 # 7 4408318687 Nodes: 4408318687, Time: 53432 ms, Nodes/s: 82501800
Praticamente sono passato da 82 a 62 ed ora 53 secondi, nella posizione di test degli arrocchi.
Mediamente, da luglio ho recuperato un ulteriore 10% di velocità, nel perft.
Ora tocca ad AlfaGemma, così potrò fare una prima partita del nuovo Drago.
30/08/2018 alle 23:09 #12246Che bello… quando i pezzi vanno al loro posto, uno dopo l’altro:
perft 7 # 1 20 # 2 400 # 3 8902 # 4 197281 # 5 4865609 # 6 119060324 # 7 3195901860 Nodes: 3195901860, Time: 35444 ms, Nodes/s: 90165096
Da 41 secondi a 35, con un’oretta di lavoro!
C’è ancora qualcosa da sistemare, credo legata ai pedoni inchiodati che prendono en-passant:
setboard r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq - 6 5 perft 6 # 1 36 # 2 1256 # 3 43408 # 4 1492118 # 5 51781599 # 6 1785497158 <<<--- deve essere 1785363392 Nodes: 1785497158, Time: 21093 ms, Nodes/s: 84644787
Sistemato quest’ultimo problema, proverò un’altra modifica, che potrebbe farmi guadagnare ancora un po’.
31/08/2018 alle 00:11 #12247Il baco era dovuto al controllo dello scacco, nel caso in cui si scopriva il RE (ad esempio: spingendo un pedone inchiodato) quando sulla diagonale/colonna c’erano due o più pezzi nemici coerenti con la linea, per dare scacco (alfiere+donna o torre+donna o due torri ecc.). La correzione rallenta un po’… la velocizzazione ma il risultato è mediamente più che positivo:
\drago perft 7 # 1 20 # 2 400 # 3 8902 # 4 197281 # 5 4865609 # 6 119060324 # 7 3195901860 Nodes: 3195901860, Time: 38348 ms, Nodes/s: 83337293 setboard r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq - 6 5 perft 6 # 1 36 # 2 1256 # 3 43408 # 4 1492118 # 5 51781599 # 6 1785363392 Nodes: 1785363392, Time: 21669 ms, Nodes/s: 82388712
Mi sto avvicinando all’obiettivo del perft attorno ai 100 Mega nodi al secondo (che poi ora conto solo le foglie, non i nodi!). Sabrina è attorno ai 50, per cui ho già quasi raddoppiato la velocità. Il merito però non è tutto dell’assembly…
08/09/2018 alle 10:51 #12259Ecco la prima partita del nuovo Drago. Ha solo il valore dei pezzi e non fa nemmeno l’ordinamento delle mosse. Queste partite credo che siano le prime che gioca ogni nuovo motore, quando è appena abbozzato… e sono straordinariamente simili a quelle che giocano i bambini alle prime armi: spingono tutti i pedoni!
.
26/10/2018 alle 18:45 #12296Seconda partita di Drago (sarà pronto, per domani???):
Qui perde per mossa illegale… ma ora lo sistemo.
27/10/2018 alle 06:08 #12297Drago ora ha solo 3 parametri, nella sua funzione di valutazione “notturna”: bonus pezzi minori al centro, penalità per pezzi minori in prima/ottava e bonus quando arrocca. Non dovrebbe vincere neanche una partita, con così poca conoscenza, ed invece:
Engine Score Dr 1: Drago 14,5/25 ····· 2: Sabrina.3.1.25.w64 3,5/5 1==1= 2: Giraffe 3,5/5 =1=1= 2: LarsenVB 3,5/5 101=1 5: DarkHorse 0,0/5 00000 5: Raffaela 0,0/5 00000
Questo è il primo (ed unico) match a 5m completo giocato finora dal nuovo Drago e lascia ben sperare. Considerate che non ha nemmeno il sort nell’iterative deepening, per cui non prova la prima mossa in ordine di risultato delle varie iterazioni! (di fatto, ogni iterazione riparte dalla prima mossa generata, non dalla migliore trovata all’iterazione precedente). Non ha TT, non ha quiescenza, non ha conoscenza dei finali, non sa cosa sia una colonna aperta o un pedone doppiato… ha meno euristiche perfino del primo Drago in MS/DOS!
Magia dell’assembly o magia del minimalismo? Lo sapremo oggi all’IGT!
PS: comunque è stabile, non si è mai piantato
02/12/2018 alle 10:43 #12436A richiesta di alcuni scacchisti che hanno ChessBase, sto implementando l’interfaccia UCI in Drago/Sabrina. Non che faccia salti di gioia, per questo, ma è comunque un’opzione interessante.
PS: ora funziona; Drago/Sabrina hanno anche l’interfaccia UCI, oltre a quella xBoard!
07/12/2018 alle 17:52 #12442Mini-test delle versioni UCI dei miei ultimi motori:
Engine Score Dr Sa S-B 1: Drago UCI 2,5/4 ···· ===1 3,75 2: Sabrina UCI 1,5/4 ===0 ···· 3,75
-
AutoreArticoli
Devi essere loggato per rispondere a questa discussione.