Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找数组中的最小元素及其索引_C++_Parallel Processing_Openmp - Fatal编程技术网

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

C++ 查找数组中的最小元素及其索引,c++,parallel-processing,openmp,C++,Parallel Processing,Openmp,使用OpenMP 3.1,可以使用min的reduce子句: 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; double-m; #pragma omp并行还原(最小:m) 对于(int i=0;i

使用OpenMP 3.1,可以使用
min
reduce
子句:

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;
double-m;
#pragma omp并行还原(最小:m)
对于(int i=0;i
假设我还需要最小元素的索引;有没有一种方法可以使用
reduce
子句?我相信另一种方法是使用
nowait
critical
手动编写reduce

假设我还需要最小元素的索引;有没有一种方法可以使用reduce子句呢

不幸的是,没有。OpenMP中可能的缩减列表非常…小。特别是,
min
max
是唯一的“高级”功能,它们根本不可定制

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

对于这样的操作,您需要通过将线程局部结果累积到线程局部变量中并在最后组合它们来实现缩减

实现这一点的最简单方法(实际上非常接近于OpenMP实现缩减的方式)是为每个线程创建一个包含元素的数组,并使用
omp\u get\u thread\u 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] …
}
结构最小元素{ 双最小值; 大小最小索引; }; size\t const CACHE\u LINE\u size=1024;//例如。 标准::向量分钟(线程数*缓存线大小); #pragma-omp并行 对于(int i=0;i
@user1071136不,我的意思是
omp\u get\u thread\u num
。我们想要的是索引,而不是总数。至于
threadnum
,这是一个占位符。您不能在这里使用
omp\u get\u num\u threads
,因为您不在并行区域内。相反,您应该实际将
numthread
作为e随后的并行子句。+1用于提及错误共享。尽管如此,OpenMP缩减子句的设计目的是提高效率和易于实现,而不是扩展性。我们可以使用
omp_get_max_threads()
要事先知道要分配多少存储空间,不是吗?另外,对于
缓存线大小
,它对我来说似乎没有太大区别,所以我可能没有尝试正确的值。对于64字节的缓存线,我们应该使用“4”吗?@user1071136是的,你可以。至于
缓存线大小
,这里的大小应该是缓存线的大小(以字节为单位)。因此,在你的例子中,是64,而不是4。1024值实际上是从GCC标准库实现的并行扩展中窃取的。他们硬编码了一个大值,或多或少独立于实际机器pla由于内存大小可以忽略不计,所以选择更大的内存可能是可以的。