En el último año de desarrollo de mi motor de ajedrez (www.chessbin.com), he pasado la mayor parte del tiempo optimizando mi código para permitir una mejor y más rápida búsqueda de movimientos. Durante ese tiempo, aprendí algunos trucos que me gustaría compartir contigo.
Medición del rendimiento
Esencialmente se puede mejorar el rendimiento de dos maneras:
- Evaluar sus nodos más rápido
- búsqueda menos nodos para llegar a la misma respuesta
Su primer problema en la optimización del código será la medición. ¿Cómo sabes que realmente has marcado la diferencia? Para ayudarlo con este problema, deberá asegurarse de registrar algunas estadísticas durante su búsqueda de movimientos. Los que capturo en mi motor de ajedrez son:
- Tiempo que tardó en buscar completo.
- Número de nodos buscó
Esto le permitirá hacer el seguimiento y evaluar los cambios. La mejor manera de abordar las pruebas es crear varios juegos guardados desde la posición de apertura, el medio juego y el final del juego. Registre el tiempo y la cantidad de nodos buscados en blanco y negro. Después de hacer cualquier cambio, generalmente realizo pruebas contra los juegos guardados anteriormente mencionados para ver si he realizado mejoras en las dos matrices anteriores: número de nodos buscados o velocidad.
Para complicar las cosas aún más, después de hacer un cambio de código puede ejecutar su motor 3 veces y obtener 3 resultados diferentes cada vez. Digamos que su motor de ajedrez encontró el mejor movimiento en 9, 10 y 11 segundos. Eso es un spread de aproximadamente 20%. Entonces, ¿ha mejorado su motor en un 10% -20% o simplemente ha variado la carga en su PC? ¿Cómo lo sabes? Para combatir esto, he agregado métodos que permitirán que mi motor juegue contra sí mismo, hará movimientos tanto para el blanco como para el negro. De esta forma puedes probar no solo la variación de tiempo sobre un movimiento, sino una serie de hasta 50 movimientos en el transcurso del juego. Si la última vez que el juego duró 10 minutos y ahora toma 9, probablemente haya mejorado su motor en un 10%. Ejecutar la prueba nuevamente debe confirmar esto.
Encontrar Rendimiento ganancias
Ahora que sabemos cómo medir mejoras de rendimiento permite discutir cómo identificar posibles mejoras de rendimiento.
Si se encuentra en un entorno .NET, el generador de perfiles .NET será su amigo. Si tiene una edición de Visual Studio for Developers, viene incorporada de forma gratuita, sin embargo, hay otras herramientas de terceros que puede usar. Esta herramienta me ha ahorrado horas de trabajo, ya que le indicará dónde está gastando su motor la mayor parte de su tiempo y le permitirá concentrarse en los puntos problemáticos. Si no tiene una herramienta de creación de perfiles, es posible que tenga que registrar las marcas de tiempo de alguna manera a medida que su motor realiza diferentes pasos. No sugiero esto. En este caso, un buen perfilador vale su peso en oro. Red Gate ANTS Profiler es caro, pero el mejor que he probado. Si no puede pagar uno, al menos utilícelo para su prueba de 14 días.
Su perfilador identificará hosco cosas para usted, sin embargo, aquí hay algunas pequeñas lecciones que he aprendido trabajando con C#:
- Hacer todo lo privado
- Lo que no se puede hacer privado, dar selló
- Hacer tantos métodos estáticos como posible.
- No hable de sus métodos, uno método largo es mejor que 4 más pequeños.
- Tablero de ajedrez almacenado como una matriz [8] [8] es más lento que una matriz de [64]
- Reemplace int con byte cuando sea posible.
- posible devolución de sus métodos desde .
- Las pilas son mejores que las listas
- Las matrices son mejores que las listas de pilas y .
- Si puede definir el tamaño de la lista antes de completarla.
- Fundir, boxear, quitar el boxeo es malo.
mayores ganancias de rendimiento:
que encuentran la generación de movimiento y el pedido es extremadamente importante. Sin embargo, aquí está el problema tal como lo veo. Si evalúa el puntaje de cada movimiento antes de ordenar y ejecutar Alpha Beta, podrá optimizar su orden de movimiento de modo que obtenga cortes Alpha Beta extremadamente rápidos. Esto se debe a que en su mayoría podrás probar la mejor jugada primero. Sin embargo, el tiempo que haya dedicado a evaluar cada movimiento se desperdiciará. Por ejemplo, puede haber evaluado el puntaje en 20 movimientos, ordenar los movimientos, probar los primeros 2 y haber recibido un punto de corte en el movimiento número 2. En teoría, el tiempo que ha gastado en los otros 18 movimientos se desperdició.
Por otro lado, si realiza una evaluación más ligera y mucho más rápida, digamos simplemente capturas, su clasificación no será tan buena y tendrá que buscar más nodos (hasta un 60% más). Por otro lado, no harías una gran evaluación en cada movimiento posible. En general, este enfoque es generalmente más rápido.
Encontrar este equilibrio perfecto entre tener suficiente información para un buen tipo y no hacer más trabajo en movimientos que no usará, le permitirá obtener grandes ganancias en su algoritmo de búsqueda. Además, si elige el enfoque de clasificación más pobre, primero deberá realizar una búsqueda más superficial, por ejemplo, pasar a la 3, ordenar su movimiento antes de entrar en la búsqueda más profunda (esto a menudo se denomina profundización iterativa). Esto mejorará significativamente su clasificación y le permitirá buscar muchos menos movimientos.
Puede editar su publicación (es decir, pregunta o respuesta) para incluir información adicional como esta. Simplemente haga clic en el enlace 'editar' debajo de la publicación. – balpha
Solo por curiosidad, ¿tiene alguna idea aproximada de lo bueno que es (en términos de calificación de Elo) su programa? Soy un gran entusiasta del ajedrez y he pensado en escribir un programa de ajedrez durante años. Sé que los programas de vanguardia son poco más que front-ends para enormes bases de datos, y me encantaría ver lo bueno que alguien puede hacer con un algoritmo de aprendizaje. –
Haré un segundo comentario de Bills. Sería realmente interesante ver tu programa de ajedrez una vez que esté operativo (o incluso ahora, parece que has trabajado mucho en él) – samoz