为什么一个向量上的多线程操作很慢
Why is multi threaded operation on one vector slow?
我有很多键(c-string(,我想预先计算它们的哈希值。我制作了一个结构,用于保存密钥数据及其哈希。我把这些结构推到向量中,然后把向量分组。每组密钥将由一个线程进行散列。
最小示例:
struct Key
{
char* data; // mostly 10 character strings
uint64_t hash; // init with 0 and compute later
};
// hash group of keys
static void hash_keys(size_t idx_start, size_t const& length)
{
size_t idx_end = idx_start + length;
for (size_t i = idx_start; i < idx_end; i++)
{
Key* k = keys[i];
// hash key by murmurhash2 or djb2 hash function
k->hash = external_hash_key(k->data);
}
}
vector<Key*> keys;
// push all keys into keys vector
external_fill_keys();
size_t num_of_keys = keys.size();
// start threads
vector<thread> workers;
size_t length = num_of_keys / NUM_OF_WORKERS;
size_t remainder = num_of_keys % NUM_OF_WORKERS;
for (size_t i = 0; i < NUM_OF_WORKERS; i++)
workers.push_back(
thread(
hash_keys,
i * length, length
)
);
hash_keys(NUM_OF_WORKERS * length, remainder);
// join threads
for (auto& worker : workers)
worker.join();
我有大约3000把钥匙。如果我用单线程运行代码——只调用hash_keys(0, keys.size())
——我得到了4.0秒的估计时间。如果我用4个工作线程运行代码,我将获得5.5秒的时间。
问题是为什么速度较慢?是否不建议从多个线程读取相同的矢量?我如何利用这些线程并在更短的时间内完成这项工作?
原来我的代码有两个问题:
- 错误共享,当一个线程更新了一个键的哈希时,它试图写入与相邻线程相同的缓存行,这大大降低了执行速度
- 每个键都是通过单个
new
调用创建的,而不是一次创建多个键(在示例中不可见,此问题发生在函数external_fill_keys
中(
解决方案是为每个线程创建独立的键数组,在连接线程后,数组将连接到一个大数组中。
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 在接收 SIGINT 操作时适当地关闭多线程 c++ 应用程序
- C++多线程操作比单线程慢
- 如何实现多线程异步操作
- 多线程文件保存操作
- 数组中的多线程写入操作
- 特征多线程操作
- 多线程队列原子操作
- OpenGL CL多线程互操作
- c++处理Linux多线程程序中的按键操作
- 提振.Asio复合操作在单线程和多线程进程
- 多线程套接字操作与进度条更新
- 多线程和动态数组/矩阵操作
- 多线程性能在执行几次操作后下降
- 启用多线程来使用std::thread:不允许操作