Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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++ 要将程序转换为健壮的OpenMP感知版本,必须做些什么?_C++_C_Openmp - Fatal编程技术网

C++ 要将程序转换为健壮的OpenMP感知版本,必须做些什么?

C++ 要将程序转换为健壮的OpenMP感知版本,必须做些什么?,c++,c,openmp,C++,C,Openmp,该程序在单个输入数据文件和单个输出数据文件上运行:它从输入中获取一个数据单元,计算数据的几个统计特征,并将这些特征输入输出 人们发现这个程序是CPU受限的:CPU的使用率始终是99%,计算比读写花费更多的时间。决定使用OpenMP将程序转换为并行处理版本,因为硬件有32个CPU可用。然而,很明显,这可能导致写入竞争条件,因为多个并行线程可能希望写入单个输出 准备此类程序以实现OpenMP感知和OpenMP安全的必要步骤是什么?只有OpenMP pragmas才能轻松实现,而无需更改代码,或者之前

该程序在单个输入数据文件和单个输出数据文件上运行:它从输入中获取一个数据单元,计算数据的几个统计特征,并将这些特征输入输出

人们发现这个程序是CPU受限的:CPU的使用率始终是99%,计算比读写花费更多的时间。决定使用OpenMP将程序转换为并行处理版本,因为硬件有32个CPU可用。然而,很明显,这可能导致写入竞争条件,因为多个并行线程可能希望写入单个输出


准备此类程序以实现OpenMP感知和OpenMP安全的必要步骤是什么?只有OpenMP pragmas才能轻松实现,而无需更改代码,或者之前必须实现一些锁定机制?

并行化代码的难度实际上取决于占用大部分时间的例程的复杂性

在进行任何并行计算之前,您应该做的第一件事是分析您的代码,并确定哪个函数确切地占用了大部分CPU时间

一旦你知道了,你需要问自己以下问题:

  • 它有数据依赖关系吗
  • 如果是,我可以通过复制某些价格合理的数据结构来消除它们吗
  • 如果不是,它们是读/写还是只读
  • 如果它们是读/写的,访问它们的频率-根据这一点选择正确的锁定机制
  • 我是否有读/写全局变量?如果是-是否可以使其成为本地线程?如果没有-摆脱他们
  • 完成所有排序后,决定将输入拆分为线程的最佳方式(有关详细信息,请参阅OpenMP调度)
  • 开始编写pragma,重新排列代码,使函数线程安全/可重入
  • 最后一点:调试,调试,调试。尝试设计可在多线程应用程序中重现的输入/输出小示例
回答最后一个问题:
stdio
库调用都是线程安全的。它们使用内部锁定

第一个
#pragma omp parallel
提示:默认情况下,所有变量都是共享的,将它们定义为不可用,并分别为每个变量指定sharing/private。这是bug的常见陷阱:

#pragma omp parallel default(none)

并行化代码的难度实际上取决于占用大部分时间的例程的复杂性

在进行任何并行计算之前,您应该做的第一件事是分析您的代码,并确定哪个函数确切地占用了大部分CPU时间

一旦你知道了,你需要问自己以下问题:

  • 它有数据依赖关系吗
  • 如果是,我可以通过复制某些价格合理的数据结构来消除它们吗
  • 如果不是,它们是读/写还是只读
  • 如果它们是读/写的,访问它们的频率-根据这一点选择正确的锁定机制
  • 我是否有读/写全局变量?如果是-是否可以使其成为本地线程?如果没有-摆脱他们
  • 完成所有排序后,决定将输入拆分为线程的最佳方式(有关详细信息,请参阅OpenMP调度)
  • 开始编写pragma,重新排列代码,使函数线程安全/可重入
  • 最后一点:调试,调试,调试。尝试设计可在多线程应用程序中重现的输入/输出小示例
回答最后一个问题:
stdio
库调用都是线程安全的。它们使用内部锁定

第一个
#pragma omp parallel
提示:默认情况下,所有变量都是共享的,将它们定义为不可用,并分别为每个变量指定sharing/private。这是bug的常见陷阱:

#pragma omp parallel default(none)

程序只有三个功能:<代码> Read <代码>,<代码>计算<代码> > <代码>写<代码>。让我们考虑程序已经变形,发现代码>计算<代码>占用99% CPU时间。如果
compute
仅对局部变量进行操作,则问题在于写入顺序,这可能与读取不一致。那么是否应该实现某种缓存前缓冲区和缓存后缓冲区?@mbaitoff是的,在这种情况下,您的代码可以很容易地并行化。如果你的输出必须是一个特定的顺序,那么你将需要它来实现类似于一个重新排序缓冲区的东西:考虑程序只有三个功能:<代码> Read <代码>,<代码>计算< /代码>和<代码>写< /代码>。让我们考虑程序已经变形,发现代码>计算<代码>占用99% CPU时间。如果
compute
仅对局部变量进行操作,则问题在于写入顺序,这可能与读取不一致。那么是否应该实现某种缓存前缓冲区和缓存后缓冲区?@mbaitoff是的,在这种情况下,您的代码可以很容易地并行化。如果您的输出必须以特定的顺序进行,那么您将需要它来实现类似于重新排序缓冲区的功能: