OpenMP threadprivate和private之间的区别

L30*_*SV. 17 parallel-processing private openmp

我正在尝试使用OpenMP并行化C程序.

我想了解更多:

  1. threadprivate指令和private子句之间的区别
  2. 在哪些情况下,我们必须使用其中任何一个.

据我所知,区别在于threadprivate的全局范围以及跨并行区域的保留值.我在几个例子中发现,当一段代码包含一些必须私有化的全局/静态变量时,这些变量包含在threadprivate列表中,并且使用copyin将它们的初始值复制到私有副本中.

但是,是否有任何规则阻止我们使用private子句来处理全局/静态变量?也许任何实施细节?

我在OpenMP3.0规范中找不到任何解释.

Kyl*_*ker 21

您必须记住的最重要的差异:

  • 甲private变量是本地的一个区域,并且将大部分时间被放置在上堆叠.变量隐私的生命周期是数据范围子句定义的持续时间.每个线程(包括主线程)都会创建原始变量的私有副本(新变量不再与原始变量存储关联).

  • 甲threadprivate另一方面变量将最有可能放置在堆或线程本地存储(即可以被看作是一个全球性的存储器本地的线程).一个threadprivate跨区域(取决于某些限制)变量仍然存在.主线程使用原始变量,所有其他线程都创建原始变量的私有副本(主变量仍然与原始变量存储关联).


  • 还有更棘手的差异:

    • 定义为private在进入构造时每个线程未定义的变量,并且在退出并行构造时未定义相应的共享变量; private指针的初始状态是undefine.

    • 但是,threadprivate除非copyin指定了子句,否则应该假定公共块中的数据在进入第一个并行区域时未定义.当threadprivate指令中出现公共块时,每个线程副本在首次使用之前初始化一次.

  • 在OpenMP规范(第2.14.2)实际上给一个很好的说明(还有更多的相关详细)中的threadprivate指令:

    threadprivate变量的每个副本以程序指定的方式初始化一次,但在第一次引用该副本之前在程序中的未指定点处初始化.threadprivate根据在基本语言中处理静态变量的方式,但是在程序中未指定的点处,释放变量的所有副本的存储.

    线程引用另一个线程的threadprivate变量副本的程序是不符合的.

    threadprivate如果执行线程切换到修改变量的另一个任务,则变量的内容可以在任务调度点上更改.有关任务调度的更多详细信息,请参见第14页的第1.3节和第113页的第2.11节.

    在parallel区域中,主线程的引用将是遇到该parallel区域的线程中的变量的副本.

    在顺序部分期间,引用将是初始线程的变量副本.初始线程的threadprivate变量副本中的数据值保证在程序中对变量的任何两个连续引用之间保持不变.

    只有满足以下所有条件时,才能threadprivate保证非初始线程变量中的数据值在两个连续的活动parallel区域之间保持不变:

    • 两个parallel区域都没有嵌套在另一个显式parallel区域内.

    • 用于执行两个parallel区域的线程数相同.

    • 用于执行两个parallel区域的线程相关性策略是相同的.

    • 在进入两个区域时,封闭任务区域中的dyn-var内部控制变量的值为falseparallel.

    如果这些条件都成立,并且如果threadprivate在两个区域中引用变量,则在其各自区域中具有相同线程号的线程将引用该变量的相同副本.