c++ - 写入多维 vector 的子元素内的元素是线程安全的吗?

标签 c++ multidimensional-array thread-safety stdvector

我正在尝试获取一个(非常)大的 vector ,并将其中的所有值重新分配给一个多维(2D) vector >。

多维 vector 在值填充之前将两个维度调整为正确的大小,以避免重新分配。

目前,我正在单线程执行此操作,但这是需要重复发生的事情,并且由于尺寸较大(〜7秒),速度非常慢。问题是我使用的线程是否安全,例如,每个 2D 元素一个线程。

一些伪代码:

vector<string> source{/*assume that it is populated by 8,000,000 strings 
of varying length*/};
vector<vector<string>> destination;

destination.resize(8);
for(loop=0;loop<8;loop++)destination[loop].resize(1000000);

//current style
for(loop=0;loop<source.size();loop++)destination[loop/1000000][loop%1000000]=source[loop];

//desired style
void Populate(int index){
    for(loop=0;loop<destination[index].size();loop++)destination[index][loop]=source[index*1000000+loop];
}

for(loop=0;loop<8;loop++)boost::thread populator(populate,loop);

认为线程版本应该可以工作,因为它们正在写入单独的二维元素。但是,我不确定写入字符串是否会破坏内容,因为它们正在调整大小。

最佳答案

仅考虑线程安全时,这很好。

Writing concurrently to distinct objects is allowed 。 C++ 认为对象是不同的,即使它们是结构中的相邻字段或同一数组中的元素。对象的数据类型在这里并不重要,因此这对于 stringint 都适用。唯一重要的是,您必须确保您操作的范围确实完全不同。如果存在任何重叠,您将面临一场数据竞赛。

但是,这里还需要考虑另一件事,那就是性能。这高度依赖于平台,因此语言标准在这里没有给您任何规则,但有一些效果需要注意。例如,数组中的相邻元素可能驻留在同一缓存行上。因此,为了使硬件能够实现语言的线程安全保证,它必须同步对这些元素的访问。例如:以一种方式对数组访问进行分区,一个线程计算出具有偶数索引的所有元素,而另一个线程计算出奇数索引,这在技术上是线程安全的,但会给硬件带来很大的压力,因为两个线程都可能竞争对于存储在同一缓存行上的数据。

同样,您的情况也存在内存总线争用。如果您的线程完成数据计算的速度比将数据写入内存的速度快得多,那么使用多个线程实际上可能不会获得任何好处,因为所有线程最终都会等待内存。

在决定并行性是否真的是解决问题的正确方法时,请记住这些事情。

关于c++ - 写入多维 vector 的子元素内的元素是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45433469/

相关文章:

c++ - 如何获取PC模型类型?

java - newKieSession 是线程安全的吗?

c++ - boost 等效于 ManualResetEvent?

javascript - jQuery 多维数组定义

c - 如何在 C/C++ 中传递对二维数组的引用?

PHP:在多维数组中使用变量作为多个键

android - AsyncTask 无法在线程 android 中工作

c++ - 从 hana::tuple_t 到 hana::tuple

boost 或其他任何 C++ crypt 库

c++ - 我可以使用为某种类型指定的分配器在 C++ 中分配另一种类型的对象吗?