首页 > 系统相关 >windows C++ 并行编程-使用 加速器 对象(下)

windows C++ 并行编程-使用 加速器 对象(下)

时间:2024-09-06 23:20:50浏览次数:5  
标签:count 示例 windows 编程 C++ 并发 OpenMP parallel size

并发运行时支持各种编程模型。 这些模型可能会与其他库的模型重叠或对其进行补充。 本部分中的文档将 OpenMP 与并发运行时进行比较,并提供有关如何迁移现有 OpenMP 代码以使用并发运行时的示例。

OpenMP 编程模型由开放标准定义,具有与 Fortran 和 C/C++ 编程语言定义完善的绑定。 OpenMP 2.0 版和 2.5 版(由 Microsoft C++ 编译器支持)都很适合迭代的并行算法;也就是说,它们在数据数组上执行并行迭代。 OpenMP 3.0 除了迭代任务外,还支持非迭代任务。

当预设了并行度,并匹配了系统上的可用资源时,OpenMP 的效率最高。 OpenMP 模型特别适合将大量运算问题分配到单一计算机的处理资源中的高性能计算。 在此方案中,硬件环境通常是固定的,开发人员可以合理期望执行该算法时拥有对所有计算资源的独占访问权限。

但是,OpenMP 可能不适合约束较少的计算环境。 例如,通过使用 OpenMP 2.0 和 2.5 来实现递归问题(如快速排序算法或搜索数据树)会更加困难。 并发运行时通过提供异步代理库和并行模式库 (PPL) 来补充 OpenMP 的功能。 异步代理库支持粗粒度任务并行性;PPL 支持更细粒度的并行任务。 并发运行时提供了并行执行操作所需的基础结构,以便可以专注于应用程序的逻辑。 但是,由于并发运行时支持各种编程模型,因此其计划开销可能大于其他并发库(如 OpenMP)。 因此,若要转换现有 OpenMP 代码以使用并发运行时,建议以增量方式测试性能。

如何:转换 OpenMP parallel for 循环以使用并发运行时

此示例演示了如何转换使用 OpenMP parallel 和 for 指令的基本循环来使用并发运行时 concurrency::parallel_for 算法。

示例 - 质数

此示例使用 OpenMP 和并发运行时来计算随机值数组中的质数计数。

// concrt-omp-count-primes.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <random>
#include <array>
#include <iostream>

using namespace concurrency;
using namespace std;

// Determines whether the input value is prime.
bool is_prime(int n)
{
   if (n < 2)
      return false;
   for (int i = 2; i < n; ++i)
   {
      if ((n % i) == 0)
         return false;
   }
   return true;
}

// Uses OpenMP to compute the count of prime numbers in an array.
void omp_count_primes(int* a, size_t size)
{
   if (size == 0)
      return;

   size_t count = 0;
   #pragma omp parallel for
      for (int i = 0; i < static_cast<int>(size); ++i)
      {
         if (is_prime(a[i])) {
            #pragma omp atomic
               ++count;
         }
      }

   wcout << L"found " << count 
         << L" prime numbers." << endl;
}

// Uses the Concurrency Runtime to compute the count of prime numbers in an array.
void concrt_count_primes(int* a, size_t size)
{
   if (size == 0)
      return;

   combinable<size_t> counts;
   parallel_for<size_t>(0, size, [&](size_t i) 
   {
      if (is_prime(a[i])) {
         counts.local()++;
      }
   });

   wcout << L"found " << counts.combine(plus<size_t>()) 
         << L" prime numbers." << endl;
}

int wmain()
{
   // The length of the array.
   const size_t size = 1000000;
   
   // Create an array and initialize it with random values.
   int* a = new int[size];
   
   mt19937 gen(42);
   for (size_t i = 0; i < size; ++i) {
      a[i] = gen();
   }

   // Count prime numbers by using OpenMP and the Concurrency Runtime.

   wcout << L"Using OpenMP..." << endl;
   omp_count_primes(a, size);

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_count_primes(a, size);

   delete[] a;
}

本示例生成以下输出。

Using OpenMP...
found 107254 prime numbers.
Using the Concurrency Runtime...
found 107254 prime numbers.

parallel_for 算法和 OpenMP 3.0 允许索引类型为有符号整型或无符号整型类型。 parallel_for 算法还确保指定的范围不会溢出有符号类型。 OpenMP 版本 2.0 和 2.5 仅允许有符号整型索引类型。 OpenMP 也不验证索引范围。

此示例使用并发运行时的版本还使用并发 concurrency::combinable 对象代替 指令来递增计数器值,无需同步。

示例 - 使用 std::array

此示例对上一示例进行了修改,从而对 对象而不是本机数组执行操作。 由于 OpenMP 版本 2.0 和 2.5 仅允许 parallel_for 构造中使用有符号整型索引类型,因此不能使用迭代器并行访问 C++ 标准库容器的元素。 并行模式库 (PPL) 提供 concurrency::parallel_for_each 算法,该算法在迭代容器(例如 C++ 标准库提供的容器)上并行执行任务。 它与 parallel_for 算法使用相同的分区逻辑。 parallel_for_each 算法类似于 C++ 标准库 std::for_each 算法,但是 parallel_for_each 算法会并行执行任务。

// Uses OpenMP to compute the count of prime numbers in an 
// array object.
template<size_t Size>
void omp_count_primes(const array<int, Size>& a)
{
   if (a.size() == 0)
      return;

   size_t count = 0;
   int size = static_cast<int>(a.size());
   #pragma omp parallel for
      for (int i = 0; i < size; ++i)
      {
         if (is_prime(a[i])) {
            #pragma omp atomic
               ++count;
         }
      }

   wcout << L"found " << count 
         << L" prime numbers." << endl;
}

// Uses the Concurrency Runtime to compute the count of prime numbers in an 
// array object.
template<size_t Size>
void concrt_count_primes(const array<int, Size>& a)
{
   if (a.size() == 0)
      return;

   combinable<size_t> counts;
   parallel_for_each(begin(a), end(a), [&counts](int n) 
   {
      if (is_prime(n)) {
         counts.local()++;
      }
   });

   wcout << L"found " << counts.combine(plus<size_t>()) 
         << L" prime numbers." << endl;
}
编译代码

复制示例代码,并将它粘贴到 Visual Studio 项目中,或粘贴到名为 concrt-omp-count-primes.cpp 的文件中,再在 Visual Studio 命令提示符窗口中运行以下命令。

cl.exe /EHsc /openmp concrt-omp-count-primes.cpp

标签:count,示例,windows,编程,C++,并发,OpenMP,parallel,size
From: https://blog.csdn.net/m0_72813396/article/details/141575637

相关文章

  • 【Windows系列】at(计划任务)
    ps:WindowsServer2012以后的版本没有at命令,只有schtasks命令nettime\\192.168.1.131#查看时间at\\192.168.1.13110:30cmd.exe/c"whoami>c:\result.txt"#结果输出到result下type\\192.168.1.131\c$\result.txt#查看执行结果at\\192.168.1.1311/delet......
  • C++中的 new 与 delete
    我们今天来学习C++中的new与delete。它们2个是C++中的关键字,作用是在freestore(C语言中的堆区)中申请空间来存放数据。存在的意义为什么我们要在freestore中去存放数据呢?——因为freestore中的生命周期是由我们程序员所控制的。在某些时刻,我们只需要暂时性地使用一些数据。在这......
  • 几大编程语言的植物大战僵尸,你更喜欢哪一个
    一、前言 植物大战僵尸,是一款不可多得的游戏,而且属于一玩就容易上头的游戏,接下来,小编将从自己经常使用的几大编程语言方面给大家实现植物大战僵尸这一游戏,下面我们一起来看看。 二、前端版本 这个版本,玩法很多,首先我们打开网页文件,如图:  点击开始按钮,然后就会出......
  • Python中的`super()`函数:解锁面向对象编程的高级技巧
    引言在面向对象的世界中,继承是一个非常重要的概念。通过继承,我们可以创建新的类来复用现有类的功能,同时还可以根据需求添加或修改功能。然而,在复杂的继承体系中,正确地调用基类的方法变得尤为重要。super()函数正是为此而生,它提供了一种简洁有效的方式来处理这类问题。本文将带你深......
  • c++一个数因子和(快速求解)
    void一个数因子和(int整数){//缘由https://ask.csdn.net/questions/1054457#answer_1251715 inthe=0,j=0;stringa=""; while(++j<整数)if(!(整数%j))he+=j,a+=to_string(j)+"+"; cout<<a<<"的因子和:"<<he......
  • Python中的方法重写与多态:解锁编程的无限可能
    在编程的世界里,灵活性与扩展性往往是衡量一个语言是否强大、易于维护的关键指标。Python,作为一种被广泛使用的高级编程语言,不仅以其简洁易读的语法赢得了众多开发者的喜爱,更因其支持多种面向对象特性而备受青睐。其中,“方法重写”与“多态”便是两个核心概念,它们不仅能够极......
  • Oracle 19c数据库:Windows详细安装与配置指南
    Oracle19c的安装和配置是一个相对复杂但系统化的过程,本文演示如何在Windows系统下安装Oracle数据库,安装足够的磁盘空间(一般需要5~6个G,所以选剩余空间大的盘)。以下是一个详细的步骤指南,包括准备工作、安装过程、配置监听器和数据库测试等关键步骤:一、下载Oracle19c安装包访问Or......
  • Python中的方法重写与多态:解锁编程的无限可能
    在编程的世界里,灵活性与扩展性往往是衡量一个语言是否强大、易于维护的关键指标。Python,作为一种被广泛使用的高级编程语言,不仅以其简洁易读的语法赢得了众多开发者的喜爱,更因其支持多种面向对象特性而备受青睐。其中,“方法重写”与“多态”便是两个核心概念,它们不仅能够极大地提高......
  • JAVAEE初阶第六节——网络编程套接字
    系列文章目录JAVAEE初阶第六节——网络编程套接字文章目录系列文章目录JAVAEE初阶第六节——网络编程套接字一.网络编程基础1.为什么需要网络编程2.什么是网络编程3.网络编程中的基本概念3.1发送端和接收端3.2请求和响应3.3客户端和服务端4.常见的客户......
  • C++初学(19)
    19.1、文本IO如果你需要写入一千份以上的数据,如果手打那可太浪费时间了。这种情况下,应该让程序直接读取文件;同样的,让程序将输入写入到文件也是更加方便。文本I/O的概念:使用cin进行输入时,程序将输入视为一系列的字节,其中每个字节都被解释为字符编码。无论目标数据类型是什么,输......