накладные расходы на синхронизацию потоков через события

Я сейчас экспериментирую с многопоточной синхронизацией. Для фона у меня есть набор из примерно 100000 объектов — возможно, больше — я хочу обрабатывать по-разному несколько раз в секунду.

Сейчас меня больше всего беспокоит производительность синхронизации.

Это то, что я думаю, должно работать нормально (я пропустил все аспекты безопасности, так как это всего лишь тестовая программа, и в случае ошибки программа просто потерпит крах ..). Я написал две функции: первая должна выполняться главным потоком программы, вторая — всеми дополнительными потоками.

void SharedWorker::Start()
{
while (bRunning)
{
// Send the command to start task1
SetEvent(hTask1Event);

// Do task1 (on a subset of all objects) here

// Wait for all workers to finish task1
WaitForMultipleObjects(<NumberOfWorkers>, <ListOfTask1WorkerEvents>, TRUE, INFINITE);

// Reset the command for task1
ResetEvent(hTask1Event);

// Send the command to start task2
SetEvent(hTask2Event);

// Do task2 (on a subset of all objects) here

// Wait for all workers to finish task2
WaitForMultipleObjects(<NumberOfWorkers>, <ListOfTask2WorkerEvents>, TRUE, INFINITE);

// Reset the command for task2
ResetEvent(hTask2Event);

// Send the command to do cleanup
SetEvent(hCleanupEvent);

// Do some (on a subset of all objects) cleanup

// Wait for all workers to finish cleanup
WaitForMultipleObjects(<NumberOfWorkers>, <ListOfCleanupWorkerEvents>, TRUE, INFINITE);

// Reset the command for cleanup
ResetEvent(hCleanupEvent);
}
}

DWORD WINAPI WorkerThreads(LPVOID lpParameter)
{
while (bRunning)
{
WaitForSingleObject(hTask1Event, INFINITE);

// Unset finished cleanup
ResetEvent(hCleanedUp);

// Do task1 (on a subset of all objects) here

// Signal finished task1
SetEvent(hTask1);

WaitForSingleObject(hTask2Event, INFINITE);

// Reset task1 event
ResetEvent(hTask1);

// Do task2 (on a subset of all objects) here

// Signal finished task2
SetEvent(hTask2);

WaitForSingleObject(hCleanupEvent, INFINITE);

// Reset update event
ResetEvent(hTask2);

// Do cleanup (on a subset of all objects) here

// Signal finished cleanup
SetEvent(hCleanedUp);
}

return 0;
}

Чтобы указать мои требования, я приведу небольшой пример:
Скажем, мы получили 100000 объектов сверху, разделенных на 8 подмножеств по 12500 объектов каждый, современный многоядерный процессор с 8 логическими ядрами. Соответствующей частью является время. Все задачи должны быть выполнены примерно за 8 мс.

Теперь у меня есть вопросы: могу ли я получить значительный прирост времени от раздельной обработки или синхронизация по событиям слишком дорога? или, может быть, есть даже другой способ синхронизации потоков с меньшими усилиями или временем процесса, если все задачи должны быть выполнены таким образом?

0

Решение

Если ваша обработка одного объекта выполняется быстро, не разделяйте его между потоками. Синхронизация потоков в Windows будет потреблять более 50 мс при каждом переключении контекста. Это время не используется системой, а только время, когда в системе выполняется что-то еще.

Однако, если обработка каждого объекта займет около 8 мсек, есть смысл планировать работу в пуле потоков. Однако обработка объектов может немного отличаться, и при большом количестве рабочие потоки завершат работу в другой момент.

Лучше всего организовать синхронизированную очередь объектов, в которую вы добавляете объекты для обработки и из которых вы берете их из обработки. Кроме того, поскольку обработка отдельного объекта значительно ниже, чем интервал планирования потока, хорошо переносить их в поток обработки партиями (например, 10-20). Вы можете оценить лучшее количество рабочих потоков в вашем пуле и лучший размер пакета с тестами.

Таким образом, псевдокод может выглядеть так:

main_thread:
init queue
start workers

set counter to 100000
add 100000 objects to queue
while (counter) wait();

worker_thread:
while (!done)
get up to 10 objects from queue
process objects
counter -= processed count
if (counter == 0) notify done
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]