欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OPENMP?SECTIONS?CONSTRUCT原理示例解析

 更新時(shí)間:2023年03月06日 09:15:52   作者:一無(wú)是處的研究僧  
這篇文章主要為大家介紹了OPENMP?SECTIONS?CONSTRUCT原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在本篇文章當(dāng)中主要給大家介紹 OpenMP 當(dāng)中主要給大家介紹 OpenMP 當(dāng)中 sections construct 的實(shí)現(xiàn)原理以及他調(diào)用的動(dòng)態(tài)庫(kù)函數(shù)分析。如果已經(jīng)了解過(guò)了前面的關(guān)于 for 的調(diào)度方式的分析,本篇文章就非常簡(jiǎn)單了。

編譯器角度分析

在這一小節(jié)當(dāng)中我們將從編譯器角度去分析編譯器會(huì)怎么處理 sections construct ,我們以下面的 sections construct 為例子,看看編譯器是如何處理 sections construct 的。

#pragma omp sections
{
  #pragma omp section
  stmt1;
  #pragma omp section
  stmt2;
  #pragma omp section
  stmt3;
}

上面的代碼會(huì)被編譯器轉(zhuǎn)換成下面的形式,其中 GOMP_sections_start 和 GOMP_sections_next 是并發(fā)安全的,他們都會(huì)返回一個(gè)數(shù)據(jù)表示第幾個(gè) omp section 代碼塊,其中 GOMP_sections_start 的參數(shù)是表示有幾個(gè) omp section 代碼塊,并且返回給線程一個(gè)整數(shù)表示線程需要執(zhí)行第幾個(gè) section 代碼塊,這兩個(gè)函數(shù)的意義不同的是在 GOMP_sections_start 當(dāng)中會(huì)進(jìn)行一些數(shù)據(jù)的初始化操作。當(dāng)兩個(gè)函數(shù)返回 0 的時(shí)候表示所有的 section 都被執(zhí)行完了,從而退出 for 循環(huán)。

for (i = GOMP_sections_start (3); i != 0; i = GOMP_sections_next ())
  switch (i)
    {
    case 1:
      stmt1;
      break;
    case 2:
      stmt2;
      break;
    case 3:
      stmt3;
      break;
    }
GOMP_barrier ();

動(dòng)態(tài)庫(kù)函數(shù)分析

事實(shí)上在函數(shù) GOMP_sections_start 和函數(shù) GOMP_sections_next 當(dāng)中調(diào)用的都是我們之前分析過(guò)的函數(shù) gomp_iter_dynamic_next ,這個(gè)函數(shù)實(shí)際上就是讓線程始終原子指令去競(jìng)爭(zhēng)數(shù)據(jù)塊(chunk),這個(gè)特點(diǎn)和 sections 需要完成的語(yǔ)意是相同的,只不過(guò) sections 的塊大?。╟hunk size)都是等于 1 的,因?yàn)橐粋€(gè)線程一次只能夠執(zhí)行一個(gè) section 代碼塊。

unsigned
GOMP_sections_start (unsigned count)
{
  // 參數(shù) count 的含義就是表示一共有多少個(gè) section 代碼塊
  // 得到當(dāng)線程的相關(guān)數(shù)據(jù)
  struct gomp_thread *thr = gomp_thread ();
  long s, e, ret;
  // 進(jìn)行數(shù)據(jù)的初始化操作
  // 將數(shù)據(jù)的 chunk size 設(shè)置等于 1
  // 分割 chunk size 的起始位置設(shè)置成 1 因?yàn)楦鶕?jù)上面的代碼分析 0 表示退出循環(huán) 因此不能夠使用 0 作為分割的起始位置
  if (gomp_work_share_start (false))
    {
    // 這里傳入 count 作為參數(shù)的原因是需要設(shè)置 chunk 分配的最終位置 具體的源代碼在下方
      gomp_sections_init (thr->ts.work_share, count);
      gomp_work_share_init_done ();
    }
  // 如果獲取到一個(gè) section 的執(zhí)行權(quán) gomp_iter_dynamic_next 返回 true 否則返回 false 
  // s 和 e 分別表示 chunk 的起始位置和終止位置 但是在 sections 當(dāng)中需要注意的是所有的 chunk size 都等于 1
  // 這也很容易理解一次執(zhí)行一個(gè) section 代碼塊
  if (gomp_iter_dynamic_next (&s, &e))
    ret = s;
  else
    ret = 0;
  return ret;
}
// 下面是部分 gomp_sections_init 的代碼
static inline void
gomp_sections_init (struct gomp_work_share *ws, unsigned count)
{
  ws->sched = GFS_DYNAMIC;
  ws->chunk_size = 1; // 設(shè)置 chunk size 等于 1
  ws->end = count + 1L; // 因?yàn)橐还灿?count 個(gè) section 塊
  ws->incr = 1; // 每次增長(zhǎng)一個(gè)
  ws->next = 1; // 從 1 開始進(jìn)行 chunk size 的分配 因?yàn)?0 表示退出循環(huán)(編譯器角度分析)
}
unsigned
GOMP_sections_next (void)
{
  // 這個(gè)函數(shù)就比較容易理解了 就是獲取一個(gè) chunk 拿到對(duì)應(yīng)的 section 的執(zhí)行權(quán)
  long s, e, ret;
  if (gomp_iter_dynamic_next (&s, &e))
    ret = s;
  else
    ret = 0;
  return ret;
}
// 下面的函數(shù)在之前的很多文章當(dāng)中都分析過(guò)了 這里不再進(jìn)行分析
// 下面的函數(shù)的主要過(guò)程就是使用 CAS 指令不斷的進(jìn)行嘗試,直到獲取成功或者全部獲取完成 沒(méi)有 chunk 需要分配
bool
gomp_iter_dynamic_next (long *pstart, long *pend)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_work_share *ws = thr->ts.work_share;
  long start, end, nend, chunk, incr;
  end = ws->end;
  incr = ws->incr;
  chunk = ws->chunk_size;
  if (__builtin_expect (ws->mode, 1))
    {
      long tmp = __sync_fetch_and_add (&ws->next, chunk);
      if (incr > 0)
  {
    if (tmp >= end)
      return false;
    nend = tmp + chunk;
    if (nend > end)
      nend = end;
    *pstart = tmp;
    *pend = nend;
    return true;
  }
      else
  {
    if (tmp <= end)
      return false;
    nend = tmp + chunk;
    if (nend < end)
      nend = end;
    *pstart = tmp;
    *pend = nend;
    return true;
  }
    }
  start = ws->next;
  while (1)
    {
      long left = end - start;
      long tmp;
      if (start == end)
  return false;
      if (incr < 0)
  {
    if (chunk < left)
      chunk = left;
  }
      else
  {
    if (chunk > left)
      chunk = left;
  }
      nend = start + chunk;
      tmp = __sync_val_compare_and_swap (&ws->next, start, nend);
      if (__builtin_expect (tmp == start, 1))
  break;
      start = tmp;
    }
  *pstart = start;
  *pend = nend;
  return true;
}

總結(jié)

在本篇文章當(dāng)中主要介紹了 OpenMP 當(dāng)中 sections 的實(shí)現(xiàn)原理和相關(guān)的動(dòng)態(tài)庫(kù)函數(shù)分析,關(guān)于 sections 重點(diǎn)在編譯器會(huì)如何對(duì) sections 的編譯指導(dǎo)語(yǔ)句進(jìn)行處理的,動(dòng)態(tài)庫(kù)函數(shù)和 for 循環(huán)的動(dòng)態(tài)調(diào)度方式是一樣的,只不過(guò) chunk size 設(shè)置成 1,分塊的起始位置等于 1,分塊的最終值是 section 代碼塊的個(gè)數(shù),最終在動(dòng)態(tài)調(diào)度的方式使用 CAS 不斷獲取 section 的執(zhí)行權(quán),指導(dǎo)所有的 section 被執(zhí)行完成。

更多精彩內(nèi)容合集可訪問(wèn)項(xiàng)目:github.com/Chang-LeHun…

以上就是OPENMP SECTIONS CONSTRUCT原理示例解析的詳細(xì)內(nèi)容,更多關(guān)于OPENMP SECTIONS CONSTRUCT 的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 對(duì)C語(yǔ)言中sizeof細(xì)節(jié)的三點(diǎn)分析介紹

    對(duì)C語(yǔ)言中sizeof細(xì)節(jié)的三點(diǎn)分析介紹

    以下是對(duì)C語(yǔ)言中sizeof的細(xì)節(jié)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • C語(yǔ)言的sleep、usleep、nanosleep等休眠函數(shù)的使用

    C語(yǔ)言的sleep、usleep、nanosleep等休眠函數(shù)的使用

    本文主要介紹了C語(yǔ)言的sleep、usleep、nanosleep等休眠函數(shù)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C++ OpenCV單峰三角閾值法Thresh_Unimodal詳解

    C++ OpenCV單峰三角閾值法Thresh_Unimodal詳解

    本文主要介紹了適合當(dāng)圖像的直方圖具有明顯單峰特征時(shí)使用,結(jié)合了三角法的原理而設(shè)計(jì)的圖像分割方法,感興趣的小伙伴可以了解一下
    2021-12-12
  • C/C++回調(diào)函數(shù)介紹

    C/C++回調(diào)函數(shù)介紹

    回調(diào)函數(shù)就是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用為調(diào)用它所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)
    2013-10-10
  • C和C++如何實(shí)現(xiàn)互相調(diào)用詳解

    C和C++如何實(shí)現(xiàn)互相調(diào)用詳解

    在學(xué)習(xí)c++中用到一些古老的c語(yǔ)言庫(kù)時(shí),在工作中我們經(jīng)常要使用C和C++混合編程,下面這篇文章主要給大家介紹了關(guān)于C和C++如何實(shí)現(xiàn)互相調(diào)用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 詳細(xì)聊聊c語(yǔ)言中的緩沖區(qū)問(wèn)題

    詳細(xì)聊聊c語(yǔ)言中的緩沖區(qū)問(wèn)題

    緩沖區(qū)又稱為緩存,它是內(nèi)存空間的一部分,也就是說(shuō)在內(nèi)存空間中預(yù)留了一定的存儲(chǔ)空間,這些存儲(chǔ)空間用來(lái)緩沖輸入或輸出的數(shù)據(jù),這部分預(yù)留的空間就叫做緩沖區(qū),這篇文章主要給大家介紹了關(guān)于c語(yǔ)言中緩沖區(qū)問(wèn)題的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • C++中constexpr與函數(shù)參數(shù)轉(zhuǎn)發(fā)的操作方法

    C++中constexpr與函數(shù)參數(shù)轉(zhuǎn)發(fā)的操作方法

    constexpr是c++11引入的關(guān)鍵字,c++11的constexpr的函數(shù)中只是支持單句代碼,c++14限制放寬,可以在里邊寫循環(huán)及邏輯判斷等語(yǔ)句,本文探討關(guān)于constexpr的函數(shù)中參數(shù)的現(xiàn)象,以及如果參數(shù)是constexpr如何做轉(zhuǎn)發(fā),感興趣的朋友一起看看吧
    2024-02-02
  • Qt利用QJson實(shí)現(xiàn)解析數(shù)組的示例詳解

    Qt利用QJson實(shí)現(xiàn)解析數(shù)組的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Qt如何利用QJson實(shí)現(xiàn)解析數(shù)組功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定幫助,需要的小伙伴可以了解一下
    2022-10-10
  • C語(yǔ)言字符串原地壓縮實(shí)現(xiàn)方法

    C語(yǔ)言字符串原地壓縮實(shí)現(xiàn)方法

    這篇文章主要介紹了C語(yǔ)言字符串原地壓縮實(shí)現(xiàn)方法,包含了字符串的遍歷與轉(zhuǎn)換等操作,是很實(shí)用的操作技巧,需要的朋友可以參考下
    2014-09-09
  • C++實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì)

    C++實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評(píng)論