从 OpenMP 循环内部访问和编辑 aN ma 时出错
error acessing and editing a Qmap from inside a OpenMP loop
我正在用 c++ 中的 openmp 做一个循环,以从 QVector 在 QMAP 中提供一些值,在某些计算机中它说 "program stopped to work" 但在某些计算机中它可以工作。
我看到 Qmap 不是线程安全的,但是我需要一个带有标签的容器(因为我使用 Qmap)来输入内部计算的结果并稍后在代码的串行部分中使用它。
我的代码示例如下:Being mystringlist
a QString
, themaps
is a QMap<QString, QMap<int, QVector<float>>>
and myvector
a QVector<float>
.
#pragma omp parallel for schedule(static) num_threads(std::thread::hardware_concurrency())
for (int i = 0; i < numb_of_iter; i++)
{
for each (auto var in mystringlist)
{
for (int j = 0; j < 33; j++)
{
themaps[var][i] << std::log10(j+1) + myvector[i];
}
}
}
此代码在串行模式下有效,但在并行块中有时会崩溃。所以我的想法是,如果有一种方法允许所有线程访问这个变量 themaps 这样它就不会崩溃,因为它们不会尝试在同一内存中写入 space,每个线程都有自己的 i
所以它们应该能够做到这一点。我不知道这样做的另一种选择,因为稍后我需要在代码中使用此变量 themaps
。
明智的解决方案:通过 mutex 保护您的共享变量。你当然为此付出了性能代价,只有在计算新值比插入数据结构花费的时间长得多的情况下,这是可以接受的。
大胆的解决方案:预分配所有字段,这样数据结构就不会因为插入而改变。
您需要考虑两个影响:
- 如果您访问不存在的
QMap
键,将创建一个新字段。地图将分离。这将更改内部数据布局。
- 如果您使用非常量方法访问地图,如果您对地图有多个引用(Qt 的写时复制习惯用法),地图也会分离。
对于 QVector
,使用 QVector::resize(n)
很简单。在此之后,您可以在 [0..n-1] 内设置任何字段值,只要没有其他人同时读取或写入该字段即可。
QMap
是另一种野兽。尽可能避免。
(只是一个提示:只有迭代器保证不会 return 一个 copy 项目。)
我正在用 c++ 中的 openmp 做一个循环,以从 QVector 在 QMAP 中提供一些值,在某些计算机中它说 "program stopped to work" 但在某些计算机中它可以工作。
我看到 Qmap 不是线程安全的,但是我需要一个带有标签的容器(因为我使用 Qmap)来输入内部计算的结果并稍后在代码的串行部分中使用它。
我的代码示例如下:Being mystringlist
a QString
, themaps
is a QMap<QString, QMap<int, QVector<float>>>
and myvector
a QVector<float>
.
#pragma omp parallel for schedule(static) num_threads(std::thread::hardware_concurrency())
for (int i = 0; i < numb_of_iter; i++)
{
for each (auto var in mystringlist)
{
for (int j = 0; j < 33; j++)
{
themaps[var][i] << std::log10(j+1) + myvector[i];
}
}
}
此代码在串行模式下有效,但在并行块中有时会崩溃。所以我的想法是,如果有一种方法允许所有线程访问这个变量 themaps 这样它就不会崩溃,因为它们不会尝试在同一内存中写入 space,每个线程都有自己的 i
所以它们应该能够做到这一点。我不知道这样做的另一种选择,因为稍后我需要在代码中使用此变量 themaps
。
明智的解决方案:通过 mutex 保护您的共享变量。你当然为此付出了性能代价,只有在计算新值比插入数据结构花费的时间长得多的情况下,这是可以接受的。
大胆的解决方案:预分配所有字段,这样数据结构就不会因为插入而改变。
您需要考虑两个影响:
- 如果您访问不存在的
QMap
键,将创建一个新字段。地图将分离。这将更改内部数据布局。 - 如果您使用非常量方法访问地图,如果您对地图有多个引用(Qt 的写时复制习惯用法),地图也会分离。
对于 QVector
,使用 QVector::resize(n)
很简单。在此之后,您可以在 [0..n-1] 内设置任何字段值,只要没有其他人同时读取或写入该字段即可。
QMap
是另一种野兽。尽可能避免。
(只是一个提示:只有迭代器保证不会 return 一个 copy 项目。)