首页 > 系统相关 >windows C++ 并行编程-并行容器和对象

windows C++ 并行编程-并行容器和对象

时间:2024-09-15 14:56:18浏览次数:3  
标签:prime factors windows 示例 并行 C++ int primes carmichael

并行模式库 (PPL) 包括几个容器和对象,这些容器和对象提供对其元素的线程安全访问。

并发容器提供对最重要操作的并发安全访问。 在这里,并发安全意味着指针或迭代器始终有效。 它不保证元素初始化或特定的遍历顺序。 这些容器的功能与 C++ 标准库提供的功能类似。 例如,concurrency::concurrent_vector 类与 std::vector 类类似,但 concurrent_vector 类允许并行追加元素。 如果并行代码需要对同一容器进行读写访问,请使用并发容器。

并发对象在组件之间并发共享。 并行计算并发对象状态的进程生成的结果与连续计算相同状态的另一个进程相同。 concurrency::combinable 类是并发对象类型的一个示例。 combinable 类允许并行执行计算,然后将这些计算组合成最终结果。 如果要使用同步机制(例如互斥体)来同步对共享变量或资源的访问,请使用并发对象。

示例代码并行计算质数和卡迈克尔数的集合。 然后,对于每个卡迈克尔数,代码计算该数的质因子。

示例:确定输入值是否为质数

下面的示例展示了 is_prime 函数,它确定输入值是否为质数,以及 is_carmichael 函数,它确定输入值是否为卡迈克尔数。

// 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;
}

// Determines whether the input value is a Carmichael number.
bool is_carmichael(const int n) 
{
   if (n < 2) 
      return false;

   int k = n;
   for (int i = 2; i <= k / i; ++i) 
   {
      if (k % i == 0) 
      {
         if ((k / i) % i == 0) 
            return false;
         if ((n - 1) % (i - 1) != 0)
            return false;
         k /= i;
         i = 1;
      }
   }
   return k != n && (n - 1) % (k - 1) == 0;
}
示例:计算质数和卡迈克尔数

下面的示例使用 is_prime 和 is_carmichael 函数来计算质数和卡迈克尔数的集合。 该示例使用 concurrency::parallel_invoke 和 concurrency::parallel_for 算法并行计算每个集。 

此示例使用 concurrency::concurrent_queue 对象保存卡迈克尔数集,因为它稍后会将该对象用作工作队列。 它使用 concurrency::concurrent_vector 对象来保存质数集,因为它稍后将循环访问此集以查找质因子。

// The maximum number to test.
const int max = 10000000;

// Holds the Carmichael numbers that are in the range [0, max).
concurrent_queue<int> carmichaels;

// Holds the prime numbers that are in the range  [0, sqrt(max)).
concurrent_vector<int> primes;

// Generate the set of Carmichael numbers and the set of prime numbers
// in parallel.
parallel_invoke(
   [&] {
      parallel_for(0, max, [&](int i) {
         if (is_carmichael(i)) {
            carmichaels.push(i);
         }
      });
   },
   [&] {
      parallel_for(0, int(sqrt(static_cast<double>(max))), [&](int i) {
         if (is_prime(i)) {
            primes.push_back(i);
         }
      });
   });
示例:查找给定值的所有质因子

以下示例展示 prime_factors_of 函数,该函数使用试除法查找给定值的所有质因子。

此函数使用 concurrency::parallel_for_each 算法循环访问质数集合。 该 concurrent_vector 对象使并行循环能够并发地向结果中添加质数。

// Finds all prime factors of the given value.
concurrent_vector<int> prime_factors_of(int n, 
   const concurrent_vector<int>& primes)
{
   // Holds the prime factors of n.
   concurrent_vector<int> prime_factors;
   
   // Use trial division to find the prime factors of n.
   // Every prime number that divides evenly into n is a prime factor of n.
   const int max = sqrt(static_cast<double>(n));
   parallel_for_each(begin(primes), end(primes), [&](int prime)
   {
      if (prime <= max)
      {         
         if ((n % prime) == 0)
            prime_factors.push_back(prime);
      }
   });

   return prime_factors;
}
 示例:处理卡迈克尔数队列中的每个元素

此示例通过调用 prime_factors_of 函数计算其质因子,来处理卡迈克尔数队列中的每个元素。 它使用任务组,以并行方式实现此操作。 有关任务组的详细信息,请参阅任务并行。

此示例为每个具有四个以上质因子的卡迈克尔数打印其质因子。

// Use a task group to compute the prime factors of each 
// Carmichael number in parallel.
task_group tasks;

int carmichael;
while (carmichaels.try_pop(carmichael))
{
   tasks.run([carmichael,&primes] 
   {
      // Compute the prime factors.
      auto prime_factors = prime_factors_of(carmichael, primes);

      // For brevity, print the prime factors for the current number only
      // if there are more than 4.
      if (prime_factors.size() > 4)
      {
         // Sort and then print the prime factors.
         sort(begin(prime_factors), end(prime_factors));

         wstringstream ss;
         ss << L"Prime factors of " << carmichael << L" are:";

         for_each (begin(prime_factors), end(prime_factors), 
            [&](int prime_factor) { ss << L' ' << prime_factor; });
         ss << L'.' << endl;

         wcout << ss.str();
      }
   });
}

// Wait for the task group to finish.
tasks.wait();
示例:完成的并行容器代码示例

以下代码展示了完整示例,该示例使用并行容器来计算卡迈克尔数的质因子。

// carmichael-primes.cpp
// compile with: /EHsc
#include <ppl.h>
#include <concurrent_queue.h>
#include <concurrent_vector.h>
#include <iostream>
#include <sstream>

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;
}

// Determines whether the input value is a Carmichael number.
bool is_carmichael(const int n) 
{
   if (n < 2) 
      return false;

   int k = n;
   for (int i = 2; i <= k / i; ++i) 
   {
      if (k % i == 0) 
      {
         if ((k / i) % i == 0) 
            return false;
         if ((n - 1) % (i - 1) != 0)
            return false;
         k /= i;
         i = 1;
      }
   }
   return k != n && (n - 1) % (k - 1) == 0;
}

// Finds all prime factors of the given value.
concurrent_vector<int> prime_factors_of(int n, 
   const concurrent_vector<int>& primes)
{
   // Holds the prime factors of n.
   concurrent_vector<int> prime_factors;
   
   // Use trial division to find the prime factors of n.
   // Every prime number that divides evenly into n is a prime factor of n.
   const int max = sqrt(static_cast<double>(n));
   parallel_for_each(begin(primes), end(primes), [&](int prime)
   {
      if (prime <= max)
      {         
         if ((n % prime) == 0)
            prime_factors.push_back(prime);
      }
   });

   return prime_factors;
}

int wmain()
{
   // The maximum number to test.
   const int max = 10000000;
   
   // Holds the Carmichael numbers that are in the range [0, max).
   concurrent_queue<int> carmichaels;

   // Holds the prime numbers that are in the range  [0, sqrt(max)).
   concurrent_vector<int> primes;
   
   // Generate the set of Carmichael numbers and the set of prime numbers
   // in parallel.
   parallel_invoke(
      [&] {
         parallel_for(0, max, [&](int i) {
            if (is_carmichael(i)) {
               carmichaels.push(i);
            }
         });
      },
      [&] {
         parallel_for(0, int(sqrt(static_cast<double>(max))), [&](int i) {
            if (is_prime(i)) {
               primes.push_back(i);
            }
         });
      });

   // Use a task group to compute the prime factors of each 
   // Carmichael number in parallel.
   task_group tasks;

   int carmichael;
   while (carmichaels.try_pop(carmichael))
   {
      tasks.run([carmichael,&primes] 
      {
         // Compute the prime factors.
         auto prime_factors = prime_factors_of(carmichael, primes);

         // For brevity, print the prime factors for the current number only
         // if there are more than 4.
         if (prime_factors.size() > 4)
         {
            // Sort and then print the prime factors.
            sort(begin(prime_factors), end(prime_factors));

            wstringstream ss;
            ss << L"Prime factors of " << carmichael << L" are:";

            for_each (begin(prime_factors), end(prime_factors), 
               [&](int prime_factor) { ss << L' ' << prime_factor; });
            ss << L'.' << endl;

            wcout << ss.str();
         }
      });
   }

   // Wait for the task group to finish.
   tasks.wait();
}

输出如下:

Prime factors of 9890881 are: 7 11 13 41 241.
Prime factors of 825265 are: 5 7 17 19 73.
Prime factors of 1050985 are: 5 13 19 23 37.

标签:prime,factors,windows,示例,并行,C++,int,primes,carmichael
From: https://blog.csdn.net/m0_72813396/article/details/141730137

相关文章

  • windows C++-并行编程-PPL任务并行(一)
    在并发运行时中,任务是执行特定作业并通常与其他任务并行运行的工作单元。任务可以分解为组织成任务组的其他更细化的任务。编写异步代码,并希望在异步操作完成之后进行某种操作时,可使用任务。例如,可以使用一个任务以异步方式从文件读取,然后使用另一个任务(延续任务,本文档稍后......
  • c++修炼之路之AVL树与红黑树
    目录一:AVL树1.AVL树的概念2.AVL树插入数据后平衡因子及更新的情况3.AVL树节点的定义 4.AVL树的插入及旋转 二:红黑树 1.红黑树的概念及性质2.红黑树节点的定义3.红黑树的插入操作情况 4.红黑树与AVL树的比较 接下来的日子会顺顺利利,万事胜意,生活明朗---------......
  • Windows基线检测及加固
    一、身份鉴别1.口令复杂度策略:控制面板->管理工具->本地安全策略->账户策略->密码策略->密码必须符合复杂性要求->已启用【Windows-sever-2008默认开启】查看是否强制密码历史设置为大于等于标准值2.口令最长生长周期策略:控制面板->管理工具->本地安全策略->账户策略->密......
  • 南沙C++信奥老师解一本通题: 1161:转进制
    ​ 题目描述】用递归算法将一个十进制数X转换成任意进制数M(M≤16)。【输入】一行两个数,第一个十进制数X,第二个为进制M。【输出】输出结果。【输入样例】3116{将十进制31转化为十六进制数}【输出样例】1F#include<iostream>usingnamespacestd;intx,m;void......
  • windows server2012 配制nginx安装为服务的时候,直接跳要安装.net框架,用自动的安装,直接
    1、上一个已成功在安装过程中的图:2、之前安装过程中错误的图:3、离线安装解决:下载.netframework3.5,然后解压后,选择指定备用源路径,然后选择.net安装包所在目录:只要指定上面全路径就可以,要看到先多目录。4、再次安装nginx服务成功:这样服务就安装成功了。参考:Win......
  • 国产RAID卡2230-10i windows&Linux操作系统安装指导
    环境准备:1.准备2个U盘。一个刻录系统,一个装载驱动2.需保持CSM为UEFI状态和PCIEDEVICESLIST 下2230-10i的卡为UEFI状态,如图:环境排查:由于......
  • C++ 定义静态成员 static 关键字不能在定义出重复出现
    定义静态成员和其他的成员函数一样,我们既可以在类的内部也可以在类的外部定义静态成员函数。当在类的外部定义静态成员时,不能重复static关键字,该关键字只出现在类内部的声明语句:voidAccount::rate(doublenewRate){interestRate=newRate;}Note:和类的所有成员一样,当我......
  • C++ 3/5 法则相关
    拷贝构造函数拷贝构造函数的第一个参数必须是一个引用类型。虽然我们可以定义一个接受非const引用的拷贝构造函数,但此参数几乎总是一个const的引用。拷贝构造函数在几种情况下都会被隐式地使用。因此,拷贝构造函数通常不应该是explicit的(参见7.5.4节,第265页)。一般情况,......
  • C++ Primer Plus 第六版中文版(上)
    参考资料:《C++PrimerPlus第六版中文版》笔记作者:Mr.Crocodile欢迎转载文章目录开始学习C++头文件命名规定名称空间`cout`、`cin`函数处理数据简单变量变量命名规则整型运算符`sizeof`和头文件climitsclimits中的符号常量变量初始化整型字面量整型字面量后缀char......
  • C++编译器的那些事
    接上文OK!Rightnow!  Let's go!C++编译器是如何工作的?C++编译器实际负责什么?我们把C++代码写成文本。就是这样,他只是一个文本文件,然后我们需要一些将文本转换为实际应用程序的方法,我们的计算机可以运行。从文本形式到实际可执行的二进制文件,我们基本上有两个主要......