删除一个线程上具有数百万个字符串的大型哈希图会影响另一个线程的性能

问题描述 投票:2回答:2

因此,我有一个C ++程序,该程序基本上可以解析巨型数据集文件,并将内容加载到内存中的hashmap中。完成后,我将指针翻转到新的内存位置,并在旧的位置调用delete。除此之外,程序正在通过查找内存映射中的内容来进行传入请求匹配。假设这些巨型地图包装在Evaluator类中:

Evaluator* oldEvaluator = mEvaluator;
Evaluator* newEvaluator = parseDataSet();
mEvaluator = newEvaluator;
delete oldEvaluator;

//And then on request processing:
mEvaluator.lookup(request)

该映射可以包含数百万个字符串对象,作为keys。它们是常规字符串,可以作为请求属性,如ip,UserAgent等,但每个都是插入到STL unordered_map中的字符串对象。

数据集会定期更新,但是在大多数情况下,程序只是针对内存中的数据集进行请求属性匹配,它很好且高效,并且没有错误,除非发生了新数据集的大量消耗的情况。使用这种大数据集的另一种方法是使用流式传输,但这是一个相对长期的解决方案。

它曾经是使用事件驱动模型的单线程程序,但是每次放置一个完整的新集合并调用销毁程序时,删除整个内容花费的时间太长,因此阻塞了请求处理。

所以我将删除此类映射到单独的线程上。问题是,现在删除和请求处理似乎同时发生,我可以看到请求处理线程上非常明显,急剧的减速。

当然,主机上还有其他进程正在运行,我确实希望2个线程能够竞争CPU周期。但是我没想到会看到请求匹配线程急剧下降,它变得如此之慢,以至于有时请求匹配在中间被CPU中断了几百毫秒才能完成其他工作。平均来说,一个请求应该在500us级别处理,但是在删除线程运行时,它的处理速度只有5毫秒,这在我看不到中断的情况下。有时cpu中断可能会长达50毫秒或120毫秒,等等。一个请求可能需要处理整个1000毫秒,这大约是整个数据结构删除占用另一个线程的时间。

了解这种减速的根本原因的最佳方法是什么? 是不是CPU或内存带宽瓶颈?我一直在想,只要将它放在一个单独的线程上,我就不会在乎它的运行速度,因为它毕竟必须一个一个地删除字符串对象,所以我没想到它会影响另一个线程...

EDIT:多亏了一些评论/回答,似乎已经指出了几种可能的原因:

  1. 内存碎片。是因为访问频率较低的字符串存储在更昂贵的内存位置(因此会导致缓存未命中),还是因为它存储在具有许多指针的unordered_map中,或者是因为系统正在进行内存压缩,同时删除了整个位置的漏洞?但是,为什么这会影响另一个线程的运行速度呢?
  2. 有一条评论提到它是由于锁定而引起的堆争用?那么,由于一个线程正忙于删除阻止访问堆内存的漏洞,因此该程序的整个堆锁定了吗?该程序故意从不分配内容,而不会同时释放其他内容,并且它只有2个线程,一个专门用于删除。
  3. 那么我该怎么办?我尝试了Jemalloc,但不确定是否可以完全正确地使用它---似乎在链接器行中包含-ljemalloc只是神奇地替换了libc的malloc?我尝试时没有任何性能差异,但可能使用错误。我的程序没有执行任何显式的malloc,所有内容都是new,大小事先未知,是的,它与指针和STL映射挂钩。

而且所有存储在Key

中的字符串都专门用于快速查找,因此即使它们会占用连续的存储空间,也无法将它们存储在带有索引的向量中,找到它们将是可怕的。因此,
  1. 如何确定以上两个内存问题是原因(任何工具/指标?)>
  2. 在不将我的消费模式更改为流媒体的情况下该如何解决?假设根本原因是以上2个,似乎我应该/同时做2件事情:1)从一个池中分配所有STL映射以及所有对象?我怎么做? 2)减少堆争用(我不知道Jemalloc是否解决了这两种情况)
  3. 因此,我有一个C ++程序,该程序基本上可以解析巨型数据集文件,并将内容加载到内存中的hashmap中。完成后,我将指针翻转到新的内存位置,并在...

c++ multithreading memory cpu
2个回答
1
投票

您可以尝试使用std::vector来存储内存。 std::vector元素是连续存储的,因此它将减少高速缓存未命中(请参阅What is a "cache-friendly" code?

因此,您将拥有一个map<???,size_t>而不是map<???,std::string>,您将有一个以上的间接方式来获取您的字符串(这意味着额外的运行时成本),但它允许您以较少的缓存丢失来迭代所有字符串。


0
投票

这将是一个冗长的答案,因为您的问题非常复杂。

© www.soinside.com 2019 - 2024. All rights reserved.