• <bdo id='wL378'></bdo><ul id='wL378'></ul>
  • <legend id='wL378'><style id='wL378'><dir id='wL378'><q id='wL378'></q></dir></style></legend>
      <tfoot id='wL378'></tfoot>
    1. <small id='wL378'></small><noframes id='wL378'>

        <i id='wL378'><tr id='wL378'><dt id='wL378'><q id='wL378'><span id='wL378'><b id='wL378'><form id='wL378'><ins id='wL378'></ins><ul id='wL378'></ul><sub id='wL378'></sub></form><legend id='wL378'></legend><bdo id='wL378'><pre id='wL378'><center id='wL378'></center></pre></bdo></b><th id='wL378'></th></span></q></dt></tr></i><div id='wL378'><tfoot id='wL378'></tfoot><dl id='wL378'><fieldset id='wL378'></fieldset></dl></div>

      1. omp 有序子句如何工作?

        How does the omp ordered clause work?(omp 有序子句如何工作?)
      2. <tfoot id='W9rL5'></tfoot>

            • <bdo id='W9rL5'></bdo><ul id='W9rL5'></ul>

                  <tbody id='W9rL5'></tbody>

                  <small id='W9rL5'></small><noframes id='W9rL5'>

                  <i id='W9rL5'><tr id='W9rL5'><dt id='W9rL5'><q id='W9rL5'><span id='W9rL5'><b id='W9rL5'><form id='W9rL5'><ins id='W9rL5'></ins><ul id='W9rL5'></ul><sub id='W9rL5'></sub></form><legend id='W9rL5'></legend><bdo id='W9rL5'><pre id='W9rL5'><center id='W9rL5'></center></pre></bdo></b><th id='W9rL5'></th></span></q></dt></tr></i><div id='W9rL5'><tfoot id='W9rL5'></tfoot><dl id='W9rL5'><fieldset id='W9rL5'></fieldset></dl></div>
                  <legend id='W9rL5'><style id='W9rL5'><dir id='W9rL5'><q id='W9rL5'></q></dir></style></legend>

                • 本文介绍了omp 有序子句如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  vector<int> v;
                  
                  #pragma omp parallel for ordered schedule(dynamic, anyChunkSizeGreaterThan1)
                      for (int i = 0; i < n; ++i){
                              ...
                              ...
                              ...
                  #pragma omp ordered
                              v.push_back(i);
                      }
                  

                  这用 n 大小的有序列表填充 v.

                  This fills v with an n sized ordered list.

                  当到达 ompordered 块时,所有线程都需要等待可能的最低迭代线程完成,但是如果没有线程被指定为特定迭代呢?还是 OpenMP 运行时库总是确保最低迭代由某个线程处理?

                  When reaching the omp ordered block all threads need to wait for the lowest iteration possible thread to finish, but what if none of the threads was appointed that specific iteration? Or does the OpenMP runtime library always make sure that the lowest iteration is handled by some thread?

                  另外,为什么建议将ordered 子句与dynamic schedule 一起使用?static schedule 会影响性能吗?

                  Also why is it suggested that ordered clause be used along with the dynamic schedule? Would static schedule affect performance?

                  推荐答案

                  ordered 子句的工作原理如下:不同的线程并发执行,直到遇到 ordered 区域,即然后以与在串行循环中执行的顺序相同的顺序顺序执行.这仍然允许一定程度的并发,特别是如果 ordered 区域之外的代码部分具有大量运行时间.

                  The ordered clause works like this: different threads execute concurrently until they encounter the ordered region, which is then executed sequentially in the same order as it would get executed in a serial loop. This still allows for some degree of concurrency, especially if the code section outside the ordered region has substantial run time.

                  没有特别的理由使用 dynamic 调度代替 static 调度和小块大小.这一切都取决于代码的结构.由于 ordered 引入了线程之间的依赖关系,如果与具有默认块大小的 schedule(static) 一起使用,第二个线程将不得不等待第一个线程完成所有迭代,那么第三个线程将不得不等待第二个线程完成它的迭代(因此也是第一个),依此类推.可以使用 3 个线程和 9 次迭代(每个线程 3 个)轻松将其可视化:

                  There is no particular reason to use dynamic schedule instead of static schedule with small chunk size. It all depends on the structure of the code. Since ordered introduces dependency between the threads, if used with schedule(static) with default chunk size, the second thread would have to wait for the first one to finish all iterations, then the third thread would have to wait for the second one to finish its iterations (and hence for the first one too), and so on. One could easily visualise it with 3 threads and 9 iterations (3 per thread):

                  tid  List of     Timeline
                       iterations
                  0    0,1,2       ==o==o==o
                  1    3,4,5       ==.......o==o==o
                  2    6,7,8       ==..............o==o==o
                  

                  = 显示线程正在并行执行代码.o 是线程正在执行 ordered 区域的时间.. 是空闲的线程,等待轮到它执行 ordered 区域.使用 schedule(static,1) 会发生以下情况:

                  = shows that the thread is executing code in parallel. o is when the thread is executing the ordered region. . is the thread being idle, waiting for its turn to execute the ordered region. With schedule(static,1) the following would happen:

                  tid  List of     Timeline
                       iterations
                  0    0,3,6       ==o==o==o
                  1    1,4,7       ==.o==o==o
                  2    2,5,8       ==..o==o==o
                  

                  我相信这两种情况的区别非常明显.使用 schedule(dynamic) 上面的图片或多或少会变得随机,因为分配给每个线程的迭代列表是不确定的.它还会增加额外的开销.仅当每次迭代的计算量不同并且进行计算所需的时间比使用动态调度所增加的开销多得多时,它才有用.

                  I believe the difference in both cases is more than obvious. With schedule(dynamic) the pictures above would become more or less random as the list of iterations assigned to each thread is non-deterministic. It would also add an additional overhead. It is only useful if the amount of computation is different for each iteration and it takes much more time to do the computation than is the added overhead of using dynamic scheduling.

                  不要担心最低编号的迭代.它通常被处理到团队中的第一个线程以准备执行代码.

                  Don't worry about the lowest numbered iteration. It is usually handled to the first thread in the team to become ready to execute code.

                  这篇关于omp 有序子句如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Constructor initialization Vs assignment(构造函数初始化 Vs 赋值)
                  Is a `=default` move constructor equivalent to a member-wise move constructor?(`=default` 移动构造函数是否等同于成员移动构造函数?)
                  Has the new C++11 member initialization feature at declaration made initialization lists obsolete?(声明时新的 C++11 成员初始化功能是否使初始化列表过时了?)
                  Order of constructor call in virtual inheritance(虚继承中构造函数调用的顺序)
                  How to use sfinae for selecting constructors?(如何使用 sfinae 选择构造函数?)
                  Initializing a union with a non-trivial constructor(使用非平凡的构造函数初始化联合)
                • <legend id='4BRab'><style id='4BRab'><dir id='4BRab'><q id='4BRab'></q></dir></style></legend>
                        <bdo id='4BRab'></bdo><ul id='4BRab'></ul>

                        <tfoot id='4BRab'></tfoot>

                      • <i id='4BRab'><tr id='4BRab'><dt id='4BRab'><q id='4BRab'><span id='4BRab'><b id='4BRab'><form id='4BRab'><ins id='4BRab'></ins><ul id='4BRab'></ul><sub id='4BRab'></sub></form><legend id='4BRab'></legend><bdo id='4BRab'><pre id='4BRab'><center id='4BRab'></center></pre></bdo></b><th id='4BRab'></th></span></q></dt></tr></i><div id='4BRab'><tfoot id='4BRab'></tfoot><dl id='4BRab'><fieldset id='4BRab'></fieldset></dl></div>
                            <tbody id='4BRab'></tbody>
                        1. <small id='4BRab'></small><noframes id='4BRab'>