查找数组中的最小元素及其索引

Finding minimal element in array, and its index

本文关键字:元素 索引 数组 查找      更新时间:2023-10-16

在OpenMP 3.1中,可以有一个带有minreduction子句:

double m;
#pragma omp parallel for reduction(min:m)
for (int i=0;i< n; i++){ 
  if (a[i]*2 < m) {
    m = a[i] * 2;
} 
return m;

假设我还需要最小元素的索引;有没有办法为此使用 reduction 子句?我相信另一种方法是使用 nowaitcritical 手动编写缩减。

假设我还需要最小元素的索引;有没有办法为此使用缩减子句?

OpenMP 中可能的减少列表非常...小。特别是,minmax是唯一的"更高级别"功能,它们不可自定义。完全。

不得不承认,我不喜欢 OpenMP 的缩减方法,正是因为它丝毫不可扩展,它只设计用于特殊情况。当然,这些都是有趣的特例,但从根本上说,这仍然是一种糟糕的方法。

对于此类操作,您需要通过将线程局部结果累积到线程局部变量并在最后组合它们来自己实现缩减。

执行此操作的最简单方法(实际上非常接近 OpenMP 实现缩减的方式)是拥有一个数组,其中包含每个线程的元素,并使用omp_get_thread_num()访问元素。但请注意,如果数组中的元素共享缓存行,这将导致性能下降,因为错误共享。要缓解此问题,请填充数组:

struct min_element_t {
    double min_val;
    size_t min_index;
};
size_t const CACHE_LINE_SIZE = 1024; // for example.
std::vector<min_element_t> mins(threadnum * CACHE_LINE_SIZE);
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    size_t const index = omp_get_thread_num() * CACHE_LINE_SIZE;
    // operate on mins[index] …
}