У меня странное поведение с std :: map (или std :: set, похоже, они ведут себя одинаково в этом сценарии). Возможно, у меня есть серьезное недоразумение о том, как это должно работать. Я использую VS2010 SP1.std :: map странный конфликт ресурсов в многопоточности
Возьмем, к примеру эта функция:
extern time_t g_nElapsed;
UINT Thread(LPVOID _param)
{
UINT nRuns = (UINT)_param;
for(UINT i=0; i<nRuns; ++i)
{
time_t _1 = time(NULL);
std::set<UINT> cRandomSet;
cRandomSet.insert(1);
cRandomSet.insert(2);
cRandomSet.insert(3);
cRandomSet.insert(4);
g_nElapsed += (time(NULL) - _1);
}
return 0;
}
Теперь, если я бегу 8 потоков с 100000 итераций каждый, g_nElapsed будет примерно 40 секунд. Если я запустил 1 нить с 800 000 итераций, g_nElapsed будет около 5 секунд. У меня создается впечатление, что g_nElapsed должен быть примерно одинаковым для любого разумного количества потоков. Так сказать, использование процессора увеличивается с количеством потоков, хотя работа остается неизменной. Однако, похоже, что какое-то соперничество ресурсов с множеством приводит к увеличению времени выполнения. Но почему? Это нить локальная ...
Я уверен, что это простое заблуждение и простое исправление, но Я не совсем уверен, в чем проблема.
Следующий код не демонстрирует такое поведение:
extern time_t g_nElapsed;
UINT Thread(LPVOID _param)
{
UINT nRuns = (UINT)_param;
for(UINT i=0; i<nRuns; ++i)
{
time_t _1 = time(NULL);
UINT n[4];
n[0] = 1;
n[1] = 1;
n[2] = 1;
n[3] = 1;
g_nElapsed += (time(NULL) - _1);
}
return 0;
}
Его блокиратор блокировки при создании/уничтожении объекта 'cRandomSet'. Кроме того, каждый 'cRandomSet.insert' может вызывать ** новый **, поэтому его блокировка тоже. – PSIAlt
(не так) красивая сторона распределения памяти ... –