Один из promises чистого функционального программирования состоит в том, что он хорошо разбирается. Я тестирую это требование, используя приложение F # со средними результатами. Моя программа запускает большое количество запросов MiniMax параллельно через Array.Parallel. Алгоритм MiniMax - это чистый функциональный код - без общего состояния, без блокировок, но очень рекурсивный, при создании и уничтожении множества значений при поиске по дереву. Нет ввода-вывода вообще - все в памяти. Каждый поиск MiniMax занимает 5-60 секунд, и я запускаю около 100 из них параллельно на быстрой коробке с 8 ядрами процессора. К сожалению, загрузка процессора достигает максимума около 65% и обычно находится в диапазоне 45-60%.
Я профилировал свое приложение с помощью Visual Studio Concurrency Visualizer и обнаружил, что он заблокирован примерно в 40% случаев. Все блокирующие вызовы, похоже, находятся в сборщике мусора .NET или других программах управления памятью .NET. Есть ли способ оптимизировать это поведение, не переписывая всю программу на языке более низкого уровня, например С++? Кажется очевидным, что проблема в том, что я создаю и уничтожаю слишком много объектов, но этого трудно избежать в идиоматическом коде F #. Возможно, я пропустил еще одну причину проблем синхронизации?
Спасибо.
Обновление: я сделал два изменения: отключил гиперпоточность и использовал gcServer в моем файле конфигурации. Это снизило время выполнения моего тестового примера с 32 до 13 секунд! Загрузка процессора также намного выше. Спасибо всем, кто внес предложения.