c++ - Omp for loop initialize vector
问题描述
I have the following code:
int main() {
vector<int> vec;
#pragma omp parallel for ordered schedule(dynamic)
for (int i = 0; i <= 300; i++) {
vec.push_back(i);
}
cout << vec.size() << endl;
}
The vector size is sometimes 285 or 294, but never 301. What i doing wrong?
解决方案
What you are seeing here is the effect of a thread unsafe function being called by multiple threads. Internally push_back
does something like the following in pseudocode
if reallocation needed:
reallocate
construct new object at &data[size]
++size
Now try to imagine different threads running the above code at the same time. What happens if both threads see the need to reallocate and attempt to do so at the same time. What if they both construct an object at &data[size]
because they both reached that point before ++size
? Note that even trying to increment on the same line as the construction won't work because they are still separate non-atomic operations.
What you really want to do is create a loop of strictly thread safe operations like the following.
int main() {
std::vector<int> vec(301);
#pragma omp parallel for
for (int i = 0; i <= 300; i++) {
vec[i]= i;
}
std::cout << vec.size() << std::endl;
}
In this case, every thread accesses vec[i]
with a unique i
. So no operations ever happen concurrently to the same objects. This is absolutely safe.
To answer your follow-up question, there is no way to push_back
concurrently into a vector. You would have to synchronize your push_back
calls which would make them slower than the non-parallel way. Another solution is to populate thread-local containers and then merge them. But whenever the simple solution I showed above is applicable it will also be faster than the alternatives.
推荐阅读
- python - 运行 tensorflow 代码时出现“错误代码 3221225501”的问题是什么
- javascript - 如何创建命令以删除 discord.js 中的角色
- javascript - 模态窗口关闭的调整
- php - 传递现有变量 int url
- wordpress - 创建更改 url 端点的简码
- c# - 为什么构建后我有这个 obj\Debug\TempPE 文件夹?[肯定不是重复的]
- java - 没有if如何解决else?
- python - 如何在两个 DataFrame 之间找到所有具有相同 ID 的记录?
- php - 重新加载页面时无法将会话变量设置为稳定值
- d3.js - 如何将带有 translate() 值的路径合并为一个(D3 / SVG)?