Я следую this tutorial, чтобы понять, как удалить замки, используя Vtune
Эта страница говорит следующее после сбора результатов Vtune:Как мы узнаем, что код является потокобезопасным?
Определение Hottest строк кода
Нажмите кнопку Точка навигации чтобы перейти к кодовой строке, которая заняла самое большое время ожидания. Усилитель VTune выделяет строку 170, вводящую критический раздел rgb_critical_section в функцию draw_task. Функция draw_task ожидала почти 27 секунд, пока выполнялась эта строка кода, и большую часть времени процессор был недостаточно использован. За это время критический раздел был рассмотрен 438 раз.
Секция rgb_critical является местом, где приложение является сериализации. Каждый поток должен дождаться, пока критическая секция будет доступной, прежде чем она сможет продолжить. Только один поток может быть в критической секции за раз. Вам необходимо оптимизировать код, чтобы сделать его более более параллельным.
Я был в состоянии следовать этому учебнику, пока я не достигну в следующий разделе: Remove the Lock
Снимите замок
rgb_critical_section был введен для защиты расчета от многопоточного доступа. Краткий анализ показывает, что код является потоком безопасным, и критический раздел действительно не нужен.
Мой вопрос: как мы узнаем, что код является потокобезопасным?
Как я уже сказал, я прокомментировал эти строки (EnterCritical ... и LeaveCritical ...) и увидел огромный прирост производительности, но я не понял, почему этот критический раздел не требуется? Какой анализ говорит нам об этом?
Соответствующий код здесь в analyze_locks.cpp:
public:
void operator() (const tbb::blocked_range <int> &r) const {
unsigned int serial = 1;
unsigned int mboxsize = sizeof(unsigned int)*(max_objectid() + 20);
unsigned int * local_mbox = (unsigned int *) alloca(mboxsize);
memset(local_mbox,0,mboxsize);
for (int y=r.begin(); y!=r.end(); ++y) {
drawing_area drawing(startx, totaly-y, stopx-startx, 1);
// Enter Critical Section to protect pixel calculation from multithreaded access (Needed?)
// EnterCriticalSection(&rgb_critical_section);
for (int x = startx; x < stopx; x++) {
color_t c = render_one_pixel (x, y, local_mbox, serial, startx, stopx, starty, stopy);
drawing.put_pixel(c);
}
// Exit from the critical section
// LeaveCriticalSection(&rgb_critical_section);
if(!video->next_frame()) tbb::task::self().cancel_group_execution();
}
}
draw_task() {}
};
Вопрос в том, осуществляется ли доступ к любой памяти более чем по одному потоку за раз. –
Нельзя «кратко» рассуждать о безопасности потоков. Например, этот код был проанализирован шаг за шагом, чтобы устранить расы данных при использовании OpenMP здесь - http://www.viva64.com/en/b/0035/print/ – SChepurin