Курсы по программированию

Формула программиста

основатель — Волосатов Евгений Витольдович
Поздравляю с 1 сентября! Система начисления Байтов работает.

Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование

  • На этом уроке мы проверим корректность ваших алгоритмов.
    Для этого мы прогоним супер-тест по генерации всех вариантов.

    * Выполнять этот урок необязательно.

    Ссылка:
    Сайт с результатами тестирования
  • Дата отправки отчёта: 21 мая 2018 г.
  • Задание выполнено: за 5 час. 10 мин.
  • Чему научился: Это будет длинный отчёт, но, надеюсь, интересный!

    В общем я решил заморочиться и сделать много ненужной работы! Опытным путём удалось выяснить, что очень большие потери идут на пересоздание board, но как уменьшить расходы на пересоздание, чтобы при этом не сбивалось расположение фигур я пока не придумал.

    Тогда я подумал, как можно ускорить расчёты и решил распараллелить метод Program.NextMoves(). Сделать по-уму через Parallels.Foreach вначале не получилось, так как получались неверные результаты, и тогда я решил схитрить и сделать через PLINQ, а заодно потестить и простой LINQ. Вначале результаты были обнадёживающие, но после нескольких тестовых запусков пошли неверные результаты в многопотоке и тогда я всё-таки разобрался, как сделать многопоточный foreach. Ещё я попытался распараллелить метод Chess.YieldValidMoves(), но из этого ничего хорошего не вышло. Точнее, все распараллеливания считали быстро, но считали ерунду :)

    В ходе тестирования выяснилось также, что просто перевод foreach в LINQ иногда быстрее. В общем я провёл следующее тестирование:
    NextMoves - простой метод из урока, NextMovesLINQ - он же, но преобразованный в LINQ, NextMovesParallel - реализованный через Parallel.Foreach
    Этими методами я вызывал следующие методы:
    YieldValidMoves - метод из Chess, стостоящий из лесенки foreach, YieldValidMovesLINQ - он же, но преобразованный в LINQ

    Результаты, полученные на моём ноутбуке с процессором i5 8250 для стартового FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1":

                        NextMoves() + YieldValidMoves() - Steps: 1 / Result: 20 / Done in 16ms
                NextMovesLINQ() + YieldValidMoves() - Steps: 1 / Result: 20 / Done in 10ms
              NextMovesParallel + YieldValidMoves() - Steps: 1 / Result: 20 / Done in 63ms

                NextMoves() + YieldValidMovesLINQ() - Steps: 1 / Result: 20 / Done in 13ms
        NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 1 / Result: 20 / Done in 6ms
    NextMovesParallel() + YieldValidMovesLINQ() - Steps: 1 / Result: 20 / Done in 38ms


                        NextMoves() + YieldValidMoves() - Steps: 2 / Result: 400 / Done in 123ms
                NextMovesLINQ() + YieldValidMoves() - Steps: 2 / Result: 400 / Done in 82ms
            NextMovesParallel() + YieldValidMoves() - Steps: 2 / Result: 400 / Done in 33ms

                NextMoves() + YieldValidMovesLINQ() - Steps: 2 / Result: 400 / Done in 94ms
        NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 2 / Result: 400 / Done in 93ms
    NextMovesParallel() + YieldValidMovesLINQ() - Steps: 2 / Result: 400 / Done in 26ms


                        NextMoves() + YieldValidMoves() - Steps: 3 / Result: 8902 / Done in 3012ms
                NextMovesLINQ() + YieldValidMoves() - Steps: 3 / Result: 8902 / Done in 2583ms
            NextMovesParallel() + YieldValidMoves() - Steps: 3 / Result: 8902 / Done in 513ms

                NextMoves() + YieldValidMovesLINQ() - Steps: 3 / Result: 8902 / Done in 3067ms
        NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 3 / Result: 8902 / Done in 2327ms
    NextMovesParallel() + YieldValidMovesLINQ() - Steps: 3 / Result: 8902 / Done in 471ms


                        NextMoves() + YieldValidMoves() - Steps: 4 / Result: 197281 / Done in 55673ms
                NextMovesLINQ() + YieldValidMoves() - Steps: 4 / Result: 197281 / Done in 54321ms
            NextMovesParallel() + YieldValidMoves() - Steps: 4 / Result: 197281 / Done in 21467ms

                NextMoves() + YieldValidMovesLINQ() - Steps: 4 / Result: 197281 / Done in 55400ms
        NextMovesLINQ() + YieldValidMovesLINQ() - Steps: 4 / Result: 197281 / Done in 55620ms
    NextMovesParallel() + YieldValidMovesLINQ() - Steps: 4 / Result: 197281 / Done in 21483ms

    Выводы:
    1) Распараллеливание вредно для глубины просчёта 1, но очень полезно начиная с 2 и далее.
    2) Использование LINQ в обоих методах для глубины 1 даёт наибольшую скорость расчётов.
    3) Начиная с глубины просчёта 2 распараллеливание очень ускоряет расчёты.
    4) Использование распараллеливания в первом методе для глубины 2 и 3 совместно с LINQ во втором методе в целом даёт наибольший эффект, за исключением NextMovesLINQ() + YieldValidMovesLINQ() для глубины 2.
    5) Совместное использование NextMovesLINQ() + YieldValidMovesLINQ(), а также NextMovesParallel() + YieldValidMovesLINQ() в глубине расчётов 4 начинает немного отставать от связок NextMovesLINQ() + YieldValidMoves() и NextMovesParallel() + YieldValidMovesLINQ().

    Это результат одного из прогонов теста на "прогретом" процессоре. Конечно на малой глубине просчётов были заметные колебания во времени исполнения, но я не стал собирать базу прогонов и вычислять средние значения. Но "на глаз" значения в среднем такие и получаются.

    Баги:
    1) В одном запуске из примерно 5 на глубине 1, несмотря на использование блокировки потоков связка NextMovesParallel() + YieldValidMoves() давало результат 21.
    2) В одном запуске из примерно 3 на глубине 1, просто использование связки NextMovesParallel() + YieldValidMovesLINQ() давало результат 21 или 22.
    3) На глубине просчётов выше 2 ошибок не замечено.

    Для других стартовых позиций я подробно быстродействие не тестировал, только проверил на соответствие верным результатам. Ошибки были только во второй стартовой позиции на сайте из шести: "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R".
    Так как в остальных 5 позициях всё было верно (за исключением лишней 1 или 2 при многопоточности на малой глубине), то, вероятно причина в том, что в коде не учитываются особые патовые ситуации.
  • Что было сложным: Заставить *почти* без ошибок работать распараллеливание.
  • Оценка видео-уроку:
Отчёт от 10080 за Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование


Отчёт от 10080 за Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование




Оцени работу

 
Сохранить страницу:

10080. --
FireWolf
FireWolf
ответить
# Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование / 2018-05-21 02:06

Сделайте поле с текстом отчёта больше! Я так старался красиво выровнять результаты :(


791. --
Валерий Жданов
Валерий Жданов
ответить
→  FireWolf  # Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование / 2018-05-21 07:01

сильный отчет! подробно всё расписано.

p.s. в связи с такими подробными отчетами вопрос к автору проекта - возможно лучше поле для подгрузки текстового файла или архива?


10558. --
Иван Воронин
Иван Воронин
ответить
→  FireWolf  # Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование / 2018-05-21 07:19

Я в телеграм чат скинул пару скринот твоего отчёта так, как вижу его я, после пары правок бутспрап дизайна, думаю так действительно было бы лучше



10080. --
FireWolf
FireWolf
ответить
# Шахматы по сети / Алгоритмы. VIP. Шахматное супертестирование / 2018-05-21 18:31

Только сейчас заметил: в Выводах пункт 5 в самом последнем слове-названии метода случайно дописал LINQ. Конечно должно быть так:

5) Совместное использование NextMovesLINQ() + YieldValidMovesLINQ(), а также NextMovesParallel() + YieldValidMovesLINQ() в глубине расчётов 4 начинает немного отставать от связок NextMovesLINQ() + YieldValidMoves() и NextMovesParallel() + YieldValidMoves().

Впрочем, это и так из таблицы понятно было, так что думаю вряд-ли кто так внимательно читал отчёт, чтобы запутаться :)


  • Отчёт оценивали:
    6452Кирилл Шмойлов+1   791Валерий Жданов+1   5394Anton+1   3922Александр+1   17947Dmitry Sinitsin+1   17443WildOrc+1   9980Timoha+1   10558Иван Воронин+1   9858Александр+1   3747Сергей+1   16218Дмитрий+1   10717OloloCode+1   9971Юрий+1   10895Danil42Russia+1   4753Андрей+1   17606Виктор+1   Посетитель+1   1Евгений Волосатов+1   4395Денис+1   6644valerys Nikola+1   16066Bodrik_torf+1   Посетитель+1   Посетитель+1   459Сергей Сергеевич+1  

Начинаем практику по языку C#





Если вы пришли без приглашения -
введите тысяча двадцать четыре (цифрами).
Чтобы стать хорошим программистом — нужно писать программы. На нашем сайте очень много практических упражнений.

После заполнения формы ты будешь подписан на рассылку «C# Вебинары и Видеоуроки», у тебя появится доступ к видеоурокам и консольным задачам.

Несколько раз в неделю тебе будут приходить письма — приглашения на вебинары, информация об акциях и скидках, полезная информация по C#.

Ты в любой момент сможешь отписаться от рассылки.


Научился: Проходить супер тест.
Трудности: Найти места в коде откуда можно считать правильные параметры шага, взятия, рокировки. Мы вызываем методы много раз за ход при различных проверках, поэтому значения считанные из метода где происходит проверка например на шаг не верны.



Научился: Научился выполнять тестирование шахматных алгоритмов. Нашел и исправил ошибки в коде.