有人可以帮我并行化这个 C++ 代码吗?

Cal*_*n00 1 c++ parallel-processing multithreading

所以我的任务是找到一种方法来并行化这个简单的 C++ 问题。问题是......我真的......真的在并行编程概念上挣扎,不知道该怎么做。应采取的步骤如下:

1) 取一个正整数 N 作为参数
2) 创建一个大小为 N 的整数数组
3) 填充范围 [1,1000] 中的整数
4) 并行查找最大整数和数组的总和
5) 打印最大的整数整数和数组的总和。

在我进入第 4 步之前,这很容易。我不知道如何并行化这段代码。我听说过诸如线程和多线程之类的概念,但我对如何在 C++ 中实现它们的想法几乎为零,并且可以真正使用一些帮助 + 对此的详细解释。我还没有找到一个对我有意义的并行化 C++ 程序的具体示例。

#include  <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(){

cout << "Enter the Size of the Array (N):  \n ";
int N;
cin >> N;

int array[N];
int largest_number = 0;
int sum = 0;

srand(time(0));
cout << "Populating Array...\n";

//  Filling up the Array  with values
    for(int i =0; i < N; i++)
    {

    array[i] =  (rand() % 1000) + 1;

    }


// Finding the largest value and calculating sum of the array
    for( int j  = 0; j < N; j++)
    {

    sum += array[j];

    if( array[j] > largest_number)
    {largest_number = array[j];}

    }

cout << "Output: \n";
cout << "Maximum:  " <<  largest_number << ";" <<  "Sum: " <<  sum;
cout << "\n";

 }
Run Code Online (Sandbox Code Playgroud)

就目前而言,代码工作正常。我只需要它来显示并行编程的实例。

就预期而言,我可以在代码上实现一个计时器来检查此代码的并行化速度有多快,但我想确保它首先工作。谢谢

Ric*_*ard 8

对于许多简单的并行问题,OpenMP 将是您的最佳选择。

它已经包含在所有 C++ 编译器中,它是一个成熟的行业标准,它提供卸载到 GPU 的功能,并且它对现有代码的侵入最小,使您可以轻松回退到串行公式。

下面,我重写了您的代码以利用 OpenMP。我还进行了其他一些更改。

我已经放弃了using namespace std线。这一行有潜在的危险,因为标准库很大,这会将所有这些都拉到全局命名空间中,在那里它可能与您可能正在使用的其他库发生冲突。

我也下降了int array[N]。这段代码一开始很危险,因为像这样的数组只能真正定义N为编译时常量。您真正需要的是动态分配。在 C++ 中,最好的方法是使用std::vector(见下文)。

最后,我们进入 for 循环。OpenMP 最适用于循环的每次迭代都是独立的情况。这意味着,如果您在将其与a[i]=3*a[i-1]. 但是,可以使您的循环适合该模式。

对 OpenMP 的调用:

#pragma omp parallel for reduction(+:sum) reduction(max:largest_number)
Run Code Online (Sandbox Code Playgroud)

告诉电脑

启动与核心数量一样多的线程,并在这些线程之间平均划分循环。为每个线程提供变量和的私有副本。每个线程完成其工作后,使用运算符将私有变量组合为全局变量。此外,使用运算符将所有私有变量组合成一个全局变量。sumlargest_numbersumsum+largest_numberlargest_numbermax

如您所见,这一行非常简洁地表示了需要完成的工作。即使您计划使用更复杂的框架,例如英特尔的线程构建块或使用 Thread Building Blocks 滚动您自己的框架std::thread,OpenMP 也可以成为对解决方案进行原型设计的好方法。它还可以很好地与 TBB 和std::thread.

//Compile with g++ main.cpp -fopenmp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>

int main(){
  std::cout << "Enter the Size of the Array (N): ";
  int N;
  std::cin >> N;

  std::vector<int> array(N);

  //WARNING: This is a poor way of choosing a seed
  srand(time(0));

  std::cout << "Populating Array...\n";
  for(int i =0; i < N; i++)
    array[i] =  (rand() % 1000) + 1; //WARNING: This is a poor way to choose random numbers

  int largest_number = 0;
  int sum = 0;

  // Finding the largest value and calculating sum of the array
  #pragma omp parallel for reduction(+:sum) reduction(max:largest_number)
  for( int j  = 0; j < N; j++){
    sum += array[j];

    if(array[j] > largest_number)
      largest_number = array[j];
  }

  std::cout << "Output: \n";
  std::cout << "Maximum:  " <<  largest_number << ";" <<  "Sum: " <<  sum;
  std::cout << "\n";
}
Run Code Online (Sandbox Code Playgroud)