Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 并行读/写哈希映射的最快解决方案是什么?_C++_Multithreading_Performance_Hashmap_Network Programming - Fatal编程技术网

C++ 并行读/写哈希映射的最快解决方案是什么?

C++ 并行读/写哈希映射的最快解决方案是什么?,c++,multithreading,performance,hashmap,network-programming,C++,Multithreading,Performance,Hashmap,Network Programming,我正在编写一个网络服务,它接收原始数据包,然后将其转换并放入队列中。还有两个工作线程从队列中获取转换后的数据包,并根据一些规则更新哈希映射。为了防止来自不同工作线程的哈希映射的并发更新,我必须使用互斥。不幸的是,使用互斥锁会对性能造成很大影响。我需要找个工作来解决这个问题 编辑: 转换后的数据包包含一个会话id,此会话id用作哈希映射键。在任何插入或更新之前,首先搜索会话id,如果没有找到会话id,则添加一个新条目,这正是我使用互斥锁的地方,否则,如果会话id已经存在,我只更新现有值,并且没有用

我正在编写一个网络服务,它接收原始数据包,然后将其转换并放入队列中。还有两个工作线程从队列中获取转换后的数据包,并根据一些规则更新哈希映射。为了防止来自不同工作线程的哈希映射的并发更新,我必须使用互斥。不幸的是,使用互斥锁会对性能造成很大影响。我需要找个工作来解决这个问题

编辑: 转换后的数据包包含一个会话id,此会话id用作哈希映射键。在任何插入或更新之前,首先搜索会话id,如果没有找到会话id,则添加一个新条目,这正是我使用互斥锁的地方,否则,如果会话id已经存在,我只更新现有值,并且没有用于值更新的互斥锁。知道我使用boost::unordered_-map作为底层哈希映射可能会有所帮助

下面是我使用的逻辑的psudo代码:

   if hash.find(session_id) then
      hash.update(value)
   else
      mutex.lock()
      hash.insert(value)
      mutex.unlock()
   end
你有什么建议

顺便说一下,这是我的工作环境和工具:

编译器:C++(gcc)

线程库:pthread


OS:Ubuntu14.04

最快的解决方案是以每个线程使用自己的数据集的方式分割数据,这样就不需要任何锁定。也许您可以通过基于一些关键数据在线程之间分发消息来达到目的

第二个最佳解决方案是使用C++ 11原子或C库函数实现读写自旋锁,参见
读写自旋锁通常允许多个并行读访问,但只允许一个写访问(当然也会阻止所有读访问)


Linux中也有读写互斥锁,但我发现它比手工实现稍慢。

最快的解决方案是以每个线程使用自己的数据集的方式分割数据,这样就不需要任何锁定。也许您可以通过基于一些关键数据在线程之间分发消息来达到目的

第二个最佳解决方案是使用C++ 11原子或C库函数实现读写自旋锁,参见
读写自旋锁通常允许多个并行读访问,但只允许一个写访问(当然也会阻止所有读访问)


Linux中也有读写互斥锁,但我发现它比手工实现慢一些。

您研究过无锁数据结构吗?你可以参考安德烈·亚历山德雷斯库(Andrei Alexandrescu)和魔法师迈克尔(Maged Michael)的一篇有趣的论文。例如,可以在Github存储库中找到一些使用类似思想的实现

尽管Facebook和Intel在某种程度上使用了锁定,但它们也提供了高性能的并发哈希映射


当然,这些方法需要一些额外的阅读和集成工作,但是如果您确定当前的锁定策略是瓶颈,那么它可能是值得的。

您研究过无锁数据结构吗?你可以参考安德烈·亚历山德雷斯库(Andrei Alexandrescu)和魔法师迈克尔(Maged Michael)的一篇有趣的论文。例如,可以在Github存储库中找到一些使用类似思想的实现

尽管Facebook和Intel在某种程度上使用了锁定,但它们也提供了高性能的并发哈希映射


当然,这些方法需要一些额外的阅读和集成工作,但是如果您确定当前的锁定策略是瓶颈,那么这可能是值得的。

我认为您需要添加从hashmap读取的频率,您更新hashmap的频率以及您拥有的hashmap读取器的数量。@SergeiKurenkov我添加了一些详细信息:)我认为您在这里有一个错误:
否则,如果会话id已经存在,我只更新现有值,并且没有用于值更新的互斥锁
。添加新密钥可能会导致hashmap重新分配内存,同时在另一个线程中访问密钥肯定会导致错误。当其他线程插入内容时,您不能在互斥锁外搜索映射。顺便说一下,我没有看到读取/秒的确切数字,写入/秒以及更新答案中的读者数量。我认为您需要添加从hashmap中读取的频率,您更新hashmap的频率以及您拥有的hashmap读取器的数量。@SergeiKurenkov我添加了一些详细信息:)我认为您在这里有一个错误:
否则,如果会话id已经存在,我只更新现有值,并且没有用于值更新的互斥锁
。添加新密钥可能会导致hashmap重新分配内存,同时在另一个线程中访问密钥肯定会导致错误。当其他线程插入内容时,您不能在互斥锁外搜索映射。顺便说一下,我没有看到读取/秒的确切数字,更新答案中的writes/second和读卡器数量。+1我喜欢将会话ID与线程关联以避免完全锁定的想法,但您需要一种机制来根据ID将读写传递给特定线程,没有ID的搜索也更困难。+1我喜欢将会话ID与线程关联以避免完全锁定的想法,但您需要一种机制来根据ID向特定线程传递读写操作,没有ID的搜索也更困难。