Il ritorno di Drago


Questa pagina ha una gerarchia - Pagina madre:Programmazione

Home Forum Programmazione Il ritorno di Drago

Questo argomento contiene 17 risposte, ha 2 partecipanti, ed è stato aggiornato da stegemma stegemma 6 mesi, 3 settimane fa.

Stai vedendo 15 articoli - dal 1 a 15 (di 18 totali)
  • Autore
    Articoli
  • #12187
    stegemma
    stegemma
    Moderatore

    “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.

    #12189
    stegemma
    stegemma
    Moderatore

    Il 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 test

    Sembra 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.

    #12195
    stegemma
    stegemma
    Moderatore

    Queste 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
    
    #12196
    stegemma
    stegemma
    Moderatore

    Dulcis 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)

    #12214
    stegemma
    stegemma
    Moderatore

    Rosicchiando 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.

    #12215
    stegemma
    stegemma
    Moderatore

    E 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).

    #12235
    stegemma
    stegemma
    Moderatore

    Tra 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
    
    #12245
    stegemma
    stegemma
    Moderatore

    Altra “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.

    #12246
    stegemma
    stegemma
    Moderatore

    Che 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’.

    #12247
    stegemma
    stegemma
    Moderatore

    Il 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…

    #12259
    stegemma
    stegemma
    Moderatore

    Ecco 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!

    .

    #12296
    stegemma
    stegemma
    Moderatore

    Seconda partita di Drago (sarà pronto, per domani???):

    Qui perde per mossa illegale… ma ora lo sistemo.

    #12297
    stegemma
    stegemma
    Moderatore

    Drago 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

    #12436
    stegemma
    stegemma
    Moderatore

    A 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!

    #12442
    stegemma
    stegemma
    Moderatore

    Mini-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
    
Stai vedendo 15 articoli - dal 1 a 15 (di 18 totali)

Devi essere loggato per rispondere a questa discussione.

© 2019 G 6 Tutti i diritti riservati - Buon divertimento!

By continuing to use the site, you agree to the use of cookies. more information

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi