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

时间:2019-02-04 22:48:06

标签: c++ multithreading parallel-processing

所以我的任务是找到一种方法来并行化这个简单的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";

 }

目前,该代码可以正常运行。我只需要它来显示并行编程的实例。

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

2 个答案:

答案 0 :(得分:4)

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

它已经包含在所有C ++编译器中,它是一个成熟的行业标准,它具有卸载到GPU的功能,并且对现有代码的侵入性最小,可让您轻松地恢复到串行格式。

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

我删除了using namespace std行。这行是潜在危险的,因为标准库是 big ,并将其全部拉到全局名称空间中,在这里它可能与您可能正在使用的其他库冲突。

我也删除了int array[N]。开头的代码很危险,因为只有在N是编译时常量的情况下,才能真正定义此类数组。您真正需要的是动态分配。在C ++中,最好的方法是使用std::vector(见下文)。

最后,我们进入了循环。 OpenMP最适合循环的每个迭代为独立的情况。这意味着如果您难以将其与a[i]=3*a[i-1]之类的代码一起使用。但是,可以使循环适合模式。

对OpenMP的调用:

#pragma omp parallel for reduction(+:sum) reduction(max:largest_number)

告诉计算机

  

启动与内核一样多的线程,并在这些线程之间平均分配循环。给每个线程自己的变量sumlargest_number private 副本。每个线程完成工作后,使用sum运算符将私有sum变量合并为全局+变量。另外,使用largest_number运算符将所有私有largest_number变量合并为全局max变量。

正如您所看到的,这一行非常简洁地表示了需要完成的工作。即使您打算使用更复杂的框架(例如Intel的线程构建模块)或使用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";
}

答案 1 :(得分:0)

使用C ++ 17:

std::vector<int> array(N);
// ...
auto sum = reduce(std::execution::par, arr.begin(), arr.end(), 0);