写入多维向量线程安全的子元素内的元素吗?

时间:2017-08-01 09:03:39

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

我正在尝试拍摄(非常)大的矢量,并将其中的所有值重新分配到多维(2D)矢量>。

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

目前,我正在做单线程,但它需要重复发生,并且由于大尺寸(~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);

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

1 个答案:

答案 0 :(得分:1)

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

Writing concurrently to distinct objects is allowed。 C ++认为对象是不同的,即使它们是结构中的相邻字段或同一数组中的元素。对象的数据类型在这里无关紧要,因此stringint的情况一样。唯一重要的是你必须确保你操作的范围真的完全不同。如果有任何重叠,您手上就会有数据竞争。

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

同样,你的情况在内存总线上存在争用。如果你的线程能够比你能够将它们写入内存更快地完成数据的计算,那么你可能实际上并没有通过使用多个线程获得任何东西,因为所有的线程最终都会等待内存。 / p>

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