2016-08-23 2 views
1

Мне поручено взять модель 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.

SQL Server results

К сожалению, я не могу отлаживать и поэтому не имеют представления о том, что происходит, и почему в нем отсутствуют некоторые симуляции и запущено несколько копий других. Когда я открываю диспетчер задач, я вижу, что в течение работы программы все три ядра остаются неиспользуемыми.

Любые мысли?

ОБНОВЛЕНИЕ: После обратной связи с Андре я рассмотрел планирование потоков и выполнение функции «ProcessParallelMonteCarloTasks».

Первое, что я заметил, это то, что некоторые потоки синхронизировались с базой данных. Я изменил мин размер пула равным количеству ядер и фиксированной эту проблему, но здесь есть порядок, в котором создаются нити и «ProcessParallelMonteCarloTasks» получает команду:

Execution order

В этом случае, диапазоны моделирования '17 -24 ', '41 -48' и '57 -64 'называются дважды и' 1-8 ', '25 -32' и '49 -56 'отсутствуют.

ОБНОВЛЕНИЕ 2: Я наблюдал за моим диспетчером задач, так как это выполняется, и установите приоритет потока на самый высокий. Я вижу, что 3 потока работают на 1 ядре, 2 потока на 2 ядра и 1 поток на четвертом ядре. Остальные 4 ядра почти бездействуют. Есть ли способ заставить его запустить 1 поток на ядро? Накладные расходы на выполнение 3 потоков на одном ядре должны быть большими.

+1

Можете ли вы быть более конкретным относительно вашего вопроса? Я не уверен, что это проблема многопоточности или простая проблема с sql INSERT. Вы сохраняете базу данных сразу после завершения одной задачи или ожидаете завершения всех симуляций и только после этого сохраните ее в базе данных? Если последнее верно, то как вы сохраняете каждый из результатов? В списке ? Дикионар ...? –

+0

Это не проблема с INSERT - пре-потоковая версия работает нормально. Когда каждая симуляция завершается, я записываю данные в базу данных (для целей отслеживания трейдинга нам нужно фиксировать результаты каждого моделирования для каждого актива). Результаты состоят из отдельных номеров и некоторых массивов. Массивы преобразуются в строку. – John

+0

Я не вижу ничего плохого в коде, который вы опубликовали. Проблема, вероятно, в другом месте (возможно, в ProcessParallelMonteCarloTasks) –

ответ

3

iStart и iEnd должны быть свежими переменными, iow объявить их внутри вашего цикла, иначе (они бесплатны), и вы в конечном итоге захватываете измененные значения.

+2

Leppie - это прекрасно. Он исправил мой вопрос! Большое спасибо за вашу помощь в этом. – John

+0

@John Я также рассмотрел бы, по крайней мере, результаты постановки где-то в другом месте, кроме SQL (даже если вы передадите их позже SQL). –

+0

Джонатан - Я обдумывал это. Мне нужно показать агрегированные результаты, когда моделирование закончилось, но нет необходимости получать гранулированные данные. Каковы ваши мысли по наиболее эффективному способу организации данных перед записью в базу данных? – John