for 循环内的多线程 - OpenMP
Multi threading inside a for loop - OpenMP
我正在尝试在C++代码中添加多线程。目标是函数内部的 for 循环。目标是减少程序的执行时间。执行需要 3.83 秒。
我试图在内部循环中添加命令#pragma omp parallel for reduction(+:sum)
(在 j for 循环之前),但这还不够。花了1.98秒。目的是将时间减少到 0.5 秒。
我做了一些研究来提高速度,有些人推荐带状挖掘方法进行矢量化以获得更好的结果。但是我还不知道如何实现它。
有人知道该怎么做吗?
代码为:
void filter(const long n, const long m, float *data, const float threshold, std::vector &result_row_ind) {
for (long i = 0; i < n; i++) {
float sum = 0.0f;
for (long j = 0; j < m; j++) {
sum += data[i*m + j];
}
if (sum > threshold)
result_row_ind.push_back(i);
}
std::sort(result_row_ind.begin(),
result_row_ind.end());
}
谢谢
如果可能,您可能希望并行化外部循环。 在 OpenMP 中执行此操作的最简单方法是执行以下操作:
#pragma omp parallel for
for (long i = 0; i < n; i++) {
float sum = 0.0f;
for (long j = 0; j < m; j++) {
sum += data[i*m + j];
}
if (sum > threshold) {
#pragma omp critical
result_row_ind.push_back(i);
}
}
std::sort(result_row_ind.begin(),
result_row_ind.end());
这有效,并且可能比并行化内部循环快得多(启动并行区域很昂贵),但它使用关键部分进行锁定以防止竞争。也可以通过在向量上使用用户定义的缩减来避免竞争,如果线程数非常大并且匹配结果的数量非常少,这可能会更慢,但否则可能会明显更快。 这不太正确,矢量类型不完整,因为它没有列出,但应该非常接近:
#pragma omp declare
reduction(CatVec: std::vector<T>:
omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end()))
initializer(omp_priv=std::vector<T>())
#pragma omp parallel for reduction(CatVec: result_row_ind)
for (long i = 0; i < n; i++) {
float sum = 0.0f;
for (long j = 0; j < m; j++) {
sum += data[i*m + j];
}
if (sum > threshold) {
result_row_ind.push_back(i);
}
}
std::sort(result_row_ind.begin(),
result_row_ind.end());
如果您有支持
执行策略的C++编译器,则可以尝试使用执行策略std::execution::par
std::for_each
,看看是否有帮助。例:
#include <iostream>
#include <vector>
#include <algorithm>
#if __has_include(<execution>)
# include <execution>
#elif __has_include(<experimental/execution_policy>)
# include <experimental/execution_policy>
#endif
// iterator to use with std::for_each
class iterator {
size_t val;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = size_t;
using difference_type = size_t;
using pointer = size_t*;
using reference = size_t&;
iterator(size_t value=0) : val(value) {}
inline iterator& operator++() { ++val; return *this; }
inline bool operator!=(const iterator& rhs) const { return val != rhs.val; }
inline reference operator*() { return val; }
};
std::vector<size_t> filter(const size_t rows, const size_t cols, const float* data, const float threshold) {
std::vector<size_t> result_row_ind;
std::vector<float> sums(rows);
iterator begin(0);
iterator end(rows);
std::for_each(std::execution::par, begin, end, [&](const size_t& row) {
const float* dataend = data + (row+1) * cols;
float& sum = sums[row];
for (const float* dataptr = data + row * cols; dataptr < dataend; ++dataptr) {
sum += *dataptr;
}
});
// pushing moved outside the threaded code to avoid using mutexes
for (size_t row = 0; row < rows; ++row) {
if (sums[row] > threshold)
result_row_ind.push_back(row);
}
std::sort(result_row_ind.begin(),
result_row_ind.end());
return result_row_ind;
}
int main() {
constexpr size_t rows = 1<<15, cols = 1<<18;
float* data = new float[rows*cols];
for (int i = 0; i < rows*cols; ++i) data[i] = (float)i / (float)100000000.;
std::vector<size_t> res = filter(rows, cols, data, 10.);
std::cout << res.size() << "n";
delete[] data;
}
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 我使用 OpenMP 的线程越多,执行时间就越长,这是怎么回事?
- OpenMP:共享同一算法的单线程和多线程实现
- 特征中的多线程(不使用 OpenMP)
- 多线程MKL OpenMP用GCC编译
- for 循环内的多线程 - OpenMP
- 随机密码生成器上的 OpenMP 多线程
- c++中的多线程递归函数,已编辑.使用OpenMP的速度比以前慢
- 多线程环境 (OpenMP) 中的 OpenCV 会导致分段错误
- C++ STL 算法(列表排序)OpenMP/多线程实现
- 多线程 (openMP) - 多少个并行线程
- 顺序比多线程- OpenMp - c++更快
- 多线程两个功能使用openMP
- OpenMP,更多线程导致减速的原因?(没有分享/没有rand()(我认为))
- 如何在MPI + openmp中启动多线程
- 在c++中使用openmp进行多线程处理
- 使用openMP在多线程for循环中创建线程