OpenACC 中parallel 和kernels的區別

Kernels構件

Kernels構件源于PGI Accelerator模型的region構件。嵌套kernels構件里的循環可能會被編譯器轉換成能在GPU上高效并行的部分。在這個過程中有三步。?

1:判斷并行中遇到的循環。

2:把抽象的并行轉換成硬件上的并行。對于NVIDIA CUDA GPU, 它會把并行的循環映射到grid層次(blockIdx) 或 thread層次(threadIdx)。OpenACC申明, gang 對應grid, vector 對應thread。編譯器可能會通過strip-mining(一種拆分循環利用緩存的技術)把一層的循環映射到多層。

3:編譯器生成并優化代碼。

?

在kernels構件中,編譯器用自動并行技術識別并行的循環。這個識別能被指令(directives)和條款(clauses)增強,比如說loop independent。使用-Minfo標志可以讓PGI 編譯器顯示編譯信息。你能看到類似Loop is parallelizable 如果編譯器認為這個循環可以被并行化。。

?

在第二步中,PGI編譯器使用目標硬件的模型去選擇循環被映射成vector并行還是gang。比如說,循環中有多個步進為1的數組時,更多的會被映射成vector(thread)并行。在NVIDIA GPU上,這種映射更傾向于生成能同時運行的代碼。同樣能用 loop gang 明確生成grid上的并行,或者用loop vector(64)生成64個thread的block。但這會造成移植上的困難。

第三步底層代碼生成和優化。

Parallel 構件

Parallel構件源于OpenMp的parallel構件。OpenMP會立即產生很多多余的線程,當運行到一個循環是,一個線程運行一部分。

同樣的,OpenACC的parallel構件也會產生多余的gangs。不同的是OpenACC的parallel在結束時沒有同步。就像帶了nowait參數的OpenMP一樣。

Kernels和parallel主要的不同是, 整個parallel構件會被變成一個kernel。比如說在CUDA中,會變成一個kernel<<<grid, block>>>();

?

舉例分析:

單個循環

???????? 在單個循環中kernels和parallel幾乎一樣。

#pragma acc kernels loopfor( i = 0; i < n; ++i )a[i] = b[i] + c[i];

等價于

 #pragma acc kernels{for( i = 0; i < n; ++i )a[i] = b[i] + c[i];}

如果a,b,c是指針的話,編譯器沒法消除指針的歧義,可能不會生成并行代碼。可以用restrict屬性/加-Msafeptr(不推薦)/jia independent子語

#pragma acc kernels loop independentfor( i = 0; i < n; ++i )a[i] = b[i] + c[i];

如果用parallel構件,就相當于告訴編譯器兩件事

  1. 把接下來的循環映射成kernel
  2. 把每一個步長分到gangs(grid)上
#pragma acc parallel loopfor( i = 0; i < n; ++i )a[i] = b[i] + c[i];

這會造成每一個block里都只有一個thread的情況。

下面一種和上面完全一致

 #pragma acc parallel{#pragma acc loopfor( i = 0; i < n; ++i )a[i] = b[i] + c[i];}

但是如果把里面的loop子語去掉

#pragma acc parallel{for( i = 0; i < n; ++i )a[i] = b[i] + c[i];}

循環就會在所有gang中運行。這是另一種浪費。

???????? 嵌套循環:

  !$acc kernels loopdo j = 1, mdo i = 1, na(j,i) = b(j,i) * alpha + c(i,j) * betaenddo
enddo

編譯器發現j被更多的數組用作stride-1索引,他會選擇把j循環作為vector并行,把i循環作為gangs并行。

但是,編譯器在這里有點自由。他可能會生成二維的grid,把i,j作為在gangs中多個block的索引。或者生成二維的block,把i,j作為vector中多個threads的索引。但是他總是尋找好性能的實現。

 !$acc parallel loopdo j = 1, mdo i = 1, na(j,i) = b(j,i) * alpha + c(i,j) * betaenddoenddo

或者

!$acc paralleldo j = 1, m!$acc loopdo i = 1, na(j,i) = b(j,i) * alpha + c(i,j) * betaenddoenddo

這樣編譯器能把i或j循環轉成vector并行。

 !$acc parallel loopdo i = 1, ndo j = 1, ma(j,i) = b(j,i) * alpha + c(i,j) * betaenddoenddo

這樣編譯器更可能會把i作為gangs并行,j作為vector并行。

不緊湊的嵌套循環(Non-tight Nested Loop)

#pragma acc kernels loopfor( i = 0; i < nrows; ++i ){double val = 0.0;int nstart = rowindex[i];int nend = rowindex[i+1];#pragma acc loop vector reduction(+:val)for( n = nstart; n < nend; ++n )val += m[n] * v[colndx[n]];r[i] = val;}

編譯器會為外循環生成gang并行,內循環vector并行

#pragma acc kernels loopfor( i = 0; i < nrows; ++i ){double val = 0.0;int nstart = rowindex[i];int nend = rowindex[i+1];for( n = nstart; n < nend; ++n )val += m[n] * v[colndx[n]];r[i] = val;}

如果沒有loop導語, 編譯器可能會把外循環在gangs和vector上并行, 或者自動把內循環vector化。

 #pragma acc parallel loopfor( i = 0; i < nrows; ++i ){double val = 0.0;int nstart = rowindex[i];int nend = rowindex[i+1];#pragma acc loop vector reduction(+:val)for( n = nstart; n < nend; ++n )val += m[n] * v[colndx[n]];r[i] = val;}

這樣,編譯器就不需要分析了。或者可以去掉loop vector reduction而讓編譯器自動尋找并行的機會。

相鄰的循環

 !$acc kernelsdo i = 1, na(i) = mob(i)*charge(i)enddodo i = 2, n-1c(i) = 0.5*(a(i-1) + a(i+1))enddo
!$acc end kernels

這兩個循環會被獨自的分析,調度和編譯。A會在第二個循環開始前結束。這和下面一樣。

 !$acc kernels loopdo i = 1, na(i) = mob(i)*charge(i)enddo!$acc kernels loopdo i = 2, n-1c(i) = 0.5*(a(i-1) + a(i+1))enddo

但是,寫成parallel構件就會很不同。

!$acc parallel!$acc loopdo i = 1, na(i) = mob(i)*charge(i)enddo!$acc loopdo i = 2, n-1c(i) = 0.5*(a(i-1) + a(i+1))enddo!$acc end parallel

兩個循環會同時被并行化,而且沒有同步操作。A可能還沒完成,第二個循環就開始了。

同樣的問題可能會在reduction中出現

 sum = 0.0!$acc kernels!$acc loop reduction(+:sum)do i = 1, nsum = sum + v(i)enddodo i = 1,nv(i) = v(i) / sumenddo!$acc end kernels

因為用的是kernel,第一個規約會在第二個循環開始前結束。

如果寫成parallel,這個依賴關系就又破了

   sum = 0.0!$acc parallel!$acc loop reduction(+:sum)do i = 1, nsum = sum + v(i)enddo!$acc loopdo i = 1,nv(i) = v(i) / sumenddo!$acc end parallel

事實上,多數教程都建議不要把reduction 和acc loop parallel 一起用。

總結:

???????? Kernels 和parallel構件都用于解決一樣的問題。區別是 kernels構件更隱含一些,給編譯器更多的自由性選擇。Parallel更加嚴格,需要程序員更多的分析。

轉載于:https://www.cnblogs.com/luxury/archive/2013/04/04/2999896.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376753.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376753.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376753.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ORACLE基本SQL語句-查詢篇

一、普通查詢 /*查詢表數據*/select * from STU /*取出前3行數據*/select * from stu where ROWNUM<3 /*模糊查詢*/select * from stu where stu_id like stu001% 說明&#xff1a;通配符“%”代表一個或者多個字符&#xff0c;通配符“_”代表一個字符。 /*別名*/select S…

三次握手建立失敗的幾種情況以及三次握手的理解

上面的圖是阻塞式socket進行通信的過程&#xff0c;阻塞的時候是操作系統內核網絡協議棧在工作 調用 connect 函數將激發 TCP 的三次握手過程&#xff0c;而且僅在連接建立成功或出錯時才返回。其中出錯返回可能有以下幾種情況&#xff1a; 1、三次握手無法建立&#xff0c;客…

db_name,instance_name,service_names,db_domain,dbid,oracle_sid等區別與聯系

最近整理了一篇文章&#xff1a;oracle listener 有網友對數據庫是否顯式設置了instance_name和service_names提出疑問。 由此引發出db_name,instance_name,oracle_sid等等這些常見的參數都代表什么意思&#xff0c;怎么取值的&#xff0c;有什么區別&#xff1f; SQL> sele…

檢測版本更新

如果我們要檢測app版本的更新&#xff0c;那么我們必須獲取當前運行app版本的版本信息和appstore 上發布的最新版本的信息。 當前運行版本信息可以通過info.plist文件中的bundle version中獲取&#xff1a; [cpp] view plaincopy NSDictionary *infoDic [[NSBundle mainBundle…

linux 啟動/關閉多個py腳本

后臺運行腳本 需求&#xff1a;很多時候我們會在 linux 服務器上執行 python 腳本&#xff0c;然而腳本程序執行的時間可能比較長&#xff0c;當耗時過長的情況下&#xff0c;我們使用 ssh 遠程登錄到 linux 服務器上容易造成超時自動斷開連接&#xff0c;當用戶注銷時&#x…

在熟練使用2B鉛筆前,請不要打開Axure

在互聯網產品領域&#xff0c;Axure已成為產品經理、產品設計師以及交互設計師的必備工具&#xff0c;從某種程度講&#xff0c;Axure幫助我們建立低保真模型&#xff0c;便于與用戶的需求驗證&#xff0c;也幫助我們構思交互細節&#xff0c;使前端和開發人員更容易理解我們的…

啟用isqlplus

iSQL*Plus是sqlplus基于web方式發布的&#xff0c;要使用它只要在服務器上開啟即可&#xff1a; [oraclelocalhost ~]$ isqlplusctl start perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE (unset), LC_ALL (unset)…

YUI 的模塊信息配置優先級關系梳理

背景 YUI的配置參數較多&#xff0c; 可以在好幾個地方配置一個module的相關信息&#xff0c; 如&#xff1a; //在全局配置&#xff0c; 所以YUI實例共享 YUI_config {modules: {w-autcomplete: {requires: [module1],path: test1.js,}},groups: {modules: {w-autocomplete: …

echarts 怎么知道鼠標點擊的哪根柱子

有個需求&#xff0c;點擊柱子&#xff0c;然后得到該柱子的信息&#xff0c;然后展示這個機房的時序圖。 第一步卡住了&#xff0c;就是不知道如何獲取柱子的序號。后參考&#xff1a;https://blog.csdn.net/zt_fucker/article/details/72461572?utm_sourceblogxgwz1 得到思路…

Oracle經典sql語句總結@sql-plus重點函數串講與sql語句案例@中文排序詳講).doc

1.經典的select sql語句 //注意&#xff1a;包含空值的數學表達式求出的結果為空值 SQL> select salcomm from emp; //連接員工編號與員工姓名這兩個字段 SQL> select empno||ename as "員工編號和員工姓名" from emp; //查詢去掉重復行的員工部門編號 SQL>…

C++模板簡單分析與舉例

C模板簡單分析與舉例 #pragma once #include <iostream> /*/ C 模板 /*/ /* --- 函數模板 --- */ /// 聲明 template <typename T1, typename T2> void TFunc(T1, T2); /// 一般定義 template <typename T1, typename T2> void TFunc(T1, T2) { std::cout &l…

flash builder4.7 for Mac升級AIRSDK詳解

使用flash builder 打包ANE時或者打包ipa時候常常會遇到AIRSDK版本低的問題&#xff0c;然而flash builder4.7默認使用的AIRSDK是3.4而flash builder4.7 中 Flex SDK中默認的AIRSDK是3.1,大家可能有疑問怎么有二個AIRSDK。我的理解是Flex SDK中的AIRSDK是低版本&#xff0c;低版…

echarts formatter鼠標懸停顯示信息

由于echarts中柱狀圖&#xff0c;鼠標放上去默認顯示的是x軸名稱以及y軸值。 而我現在需要再添加一些顯示信息。 下面是操作&#xff1a; 在tooltip對象中補充trigger: “axis”,屬性&#xff0c;然后再設置formatter。 tooltip : {formatter: function (params) {// do some …

codeforces 261 D

題目鏈接&#xff1a; 解題報告&#xff1a;給出一個序列a1,a2,a3.........an&#xff0c;f(i , j ,x) ak 等于x的個數(i < k < j)&#xff0c;令i < j&#xff0c;求有多少對 i 和 j 使得 f(1,i,ai) > f(j,n,aj)。 從左往右掃一遍這個序列&#xff0c;num1[i] 等于…

javascript下漢字和Unicode編碼互轉代碼

近日在為網站做一資料功能&#xff0c;這些顯示在頁面上面的文字數據都是存放在js文件裏面的&#xff0c;由於這些js文件裏面的中文都是經過unicode編碼的&#xff0c;頁面上顯示是沒有問題的&#xff0c;問題是我做的網站是繁體中文&#xff0c;而js文件裏面的中文數據是簡體中…

python 線程異步執行踩坑

有個需求&#xff0c;一個線程在得到n個數據之后&#xff0c;異步地執行一個子線程函數&#xff0c;在子線程函數中完成數據庫的打開、寫入數據、關閉操作。在子線程函數返回前父線程先返回結果。 在此之前&#xff0c;先導入我們需要的模塊&#xff1a; from concurrent.futu…

關于window.history.back()后退問題

Windows下的window.history.back()后退后返回的不僅僅是前一個頁而是前一個頁的狀態。假設一個頁我改動了3次那必須后退3次才干回到前一個頁。并且數據庫中刪除的數據依舊顯示在上面感覺很的不有用。 解決的方法&#xff1a;history.back()后再加一個reload()這樣就能夠回到刷新…

每日英語:Smog Levels in Hong Kong Hit Highs

Hong Kong’s pollution levels hit nearly decade-level highs this week, sending locals scurrying inside and obscuring the city’s skyline behind a blanket of white. scurry&#xff1a;急跑&#xff0c;急趕    In the city’s central business district, road…

轉載 | pymysql.err.InterfaceError: (0, ‘‘)解決辦法

導致這個錯誤的原因是通過pymysql連接MySQL&#xff0c;沒有關閉連接的操作&#xff0c;所以短時間內不會出問題&#xff0c;長時間保持這個連接會出現連接混亂。雖然看著自己的代碼沒錯&#xff0c;還是會報 pymysql.err.InterfaceError: (0, ‘’)錯誤。所以這個連接要么連上…

不使用物理引擎,自己動手做真實物理的模擬投籃游戲

最近打算做一個2D投籃游戲&#xff0c;由于對于BOX2D等物理引擎并不熟悉&#xff0c;加之一開始低估了游戲所需要的碰撞檢測復雜度&#xff0c;認為僅僅涉及4面墻&#xff0c;籃球&#xff0c;籃板&#xff0c;籃筐&#xff0c;籃網的碰撞檢測并不復雜。因此決定自己實現所需要…