Мне поручено взять модель monte-carlo и использовать многопоточность, чтобы она работала быстрее. Поскольку это monte-carlo, каждое симуляция не зависит от следующего. Я хочу вручную создать каждый поток, поскольку каждый из них будет запускать много тысяч симуляций и хранить результаты каждого моделирования в базе данных, и я хочу создать столько потоков, сколько есть ядер в процессоре, и дать им высокий приоритет.Многопоточность в C# (.Net 4.5) для monte-carlo
Вот основной код, используемый для управления этим (я тестирую с небольшим количеством имитаций):
var threads = new List<Thread>();
iNumCores = Environment.ProcessorCount;
iSims = 64;
iNumSimsPerThread = iSims/iNumCores;
for (int iThread = 0; iThread < iNumCores; iThread++)
{
iStart = (iThread * iNumSimsPerThread) + 1;
iEnd = ((iThread + 1) * iNumSimsPerThread);
Thread thread = new Thread(() => ProcessParallelMonteCarloTasks(iStart, iEnd, iSims));
thread.Priority = ThreadPriority.AboveNormal;
thread.Start();
threads.Add(thread);
}
foreach (var thread in threads)
thread.Join();
Моя машина имеет 8 ядер, поэтому этот тест должен создать 8 потоков, каждый из которых выполняет 8 моделирования , Когда я записываю результирующие данные в базу данных, я включаю номер модели. Я ожидал бы увидеть 64 строки с 1 на симуляцию.
Тем не менее, я получаю 1 строку для каждого моделирования до 40, а затем разрыв до 57 и затем 3 строк для каждого моделирования между 57 и 64.
К сожалению, я не могу отлаживать и поэтому не имеют представления о том, что происходит, и почему в нем отсутствуют некоторые симуляции и запущено несколько копий других. Когда я открываю диспетчер задач, я вижу, что в течение работы программы все три ядра остаются неиспользуемыми.
Любые мысли?
ОБНОВЛЕНИЕ: После обратной связи с Андре я рассмотрел планирование потоков и выполнение функции «ProcessParallelMonteCarloTasks».
Первое, что я заметил, это то, что некоторые потоки синхронизировались с базой данных. Я изменил мин размер пула равным количеству ядер и фиксированной эту проблему, но здесь есть порядок, в котором создаются нити и «ProcessParallelMonteCarloTasks» получает команду:
В этом случае, диапазоны моделирования '17 -24 ', '41 -48' и '57 -64 'называются дважды и' 1-8 ', '25 -32' и '49 -56 'отсутствуют.
ОБНОВЛЕНИЕ 2: Я наблюдал за моим диспетчером задач, так как это выполняется, и установите приоритет потока на самый высокий. Я вижу, что 3 потока работают на 1 ядре, 2 потока на 2 ядра и 1 поток на четвертом ядре. Остальные 4 ядра почти бездействуют. Есть ли способ заставить его запустить 1 поток на ядро? Накладные расходы на выполнение 3 потоков на одном ядре должны быть большими.
Можете ли вы быть более конкретным относительно вашего вопроса? Я не уверен, что это проблема многопоточности или простая проблема с sql INSERT. Вы сохраняете базу данных сразу после завершения одной задачи или ожидаете завершения всех симуляций и только после этого сохраните ее в базе данных? Если последнее верно, то как вы сохраняете каждый из результатов? В списке? Дикионар ...? –
Это не проблема с INSERT - пре-потоковая версия работает нормально. Когда каждая симуляция завершается, я записываю данные в базу данных (для целей отслеживания трейдинга нам нужно фиксировать результаты каждого моделирования для каждого актива). Результаты состоят из отдельных номеров и некоторых массивов. Массивы преобразуются в строку. – John
Я не вижу ничего плохого в коде, который вы опубликовали. Проблема, вероятно, в другом месте (возможно, в ProcessParallelMonteCarloTasks) –