我有一个非常耗时的功能,需要使用std::vector
中的每两个元素进行一些计算。我现在的方式是,
std::vector<int> vec;
for (auto it = vec.begin(); it != vec.end(); ++ it)
for (auto it2 = vec.begin(); it2 != vec.end(); ++ it2)
if (it2 != it)
f(*it, *it2) // the function
我想知道是否还有其他更好的方法可以做到这一点,因为这个过程花费了太多时间。
此外,我尝试使用OpenMP来并行化外部循环,当我使用std::vector
时它可以正常工作,但如果我使用std::map
执行类似的操作,则会返回分段错误。
并行for循环的更新。
我正在做的是使用音乐标签计算音乐相似度。每首音乐的标签位于名为std::map
的{{1}}中,所有歌曲ID都位于名为map_tag
的{{1}}中。我这里没有使用vector
,我的代码的主要部分如下。从song_vec
读取数据时似乎发生了问题,因为如果删除此部分,则并行循环可以正常工作。
iterator
另一个更新,我在问题部分之前添加了map_tag
,程序可以正常工作。我不明白故障是如何引起的,因为unsigned int finishCount = 0;
std::map<std::string, std::vector<std::string>> map_tag;
#pragma omp parallel shared(finishCount) num_threads(2)
{
#pragma omp for
for (std::size_t i = 0; i < numOfDoc; ++ i) // numOfDoc is number of music
{
std::string song_id = song_vec[i];
std::vector<std::string> song_tag;
song_tag = map_tag[song_id]; // problems here
for (std::size_t j = 0; j < numOfDoc; ++ j)
{
std::string song_id2 = song_vec[j];
std::vector<std::string> song_tag2;
song_tag2 = map_tag[song_id2]; // problems here
if (song_id != song_id2)
calSimilarity(song_tag, song_tag2);
}
// so somethings here
#pragma omp critical // use this show progress
{
finishCount ++;
cout << finishCount << "\r";
cout.flush();
}
}
}
是一个只读变量,它不能在循环内修改。
我对C ++很陌生,感谢你们所有的帮助。
答案 0 :(得分:1)
首先,改变一下:
std::vector<int> vec;
for (auto it = vec.begin(); it != vec.end(); ++ it)
for (auto it2 = vec.begin(); it2 != vec.end(); ++ it2)
if (it2 != it)
f(*it, *it2) // the function
对此:
std::vector<int> vec;
/// hopefully fill vec with something here... :(
for (auto it = vec.begin(); it != vec.end(); ++ it)
for (auto it2 = next(it); it2 != vec.end(); ++ it2) /// SEE INITIAL IT2 VALUE
f(*it, *it2) // the function
你已经将迭代次数减少了一半以上。
你正在做很多重复的工作。每个内循环调用f()
vec.size()-1
次。
从那里开始,看看你需要的地方。此外,您的问题中没有任何特定于OpenMP的内容,我无法分辨您的并行化发生的位置。请使用更多代码或详细信息进行更新。