gpt4 book ai didi

c++ - std::map 多线程中的奇怪资源争用

转载 作者:行者123 更新时间:2023-11-28 00:48:52 25 4
gpt4 key购买 nike

我对 std::map(或 std::set,它们在这种情况下的行为似乎相同)有一个奇怪的行为。可能是我对它应该如何工作有严重的误解。我正在使用 VS2010 SP1。

以这个函数为例:

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 个线程,每个线程迭代 100,000 次,g_nElapsed 将大约为 40 秒。如果我以 800,000 次迭代运行 1 个线程,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;
}

最佳答案

您正在创建和销毁许多容器,每个容器都使用 operator new 分配内存。在许多系统上,这需要同步来管理像您这样的典型的小分配分配的空闲内存。所以你可能在那里招致了相当多的线程间争用。

您可以尝试不同的分配器,例如 tcmalloc ( http://goog-perftools.sourceforge.net/doc/tcmalloc.html )。它专门用于处理此问题。

另一种方法是使用对象池或其他分配策略来完全避免使用标准分配机制。这将需要更改一些代码,而使用 tcmalloc 则不需要。

关于c++ - std::map 多线程中的奇怪资源争用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15089366/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com