自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

蘋果開發(fā)語言O(shè)penCL 變量地址限定符詳解 附源碼

移動開發(fā) iOS
本文介紹的是蘋果開發(fā)語言O(shè)penCL 變量地址限定符詳解,富有源碼可以參考學(xué)習(xí),先來看內(nèi)容。

蘋果開發(fā)語言OpenCL 變量地址限定符詳解是本文要介紹的內(nèi)容,首先我們先來了解OpenCL,即:Open Computing Language,是由蘋果公司起草設(shè)計的用于大規(guī)模并行計算的計算編程語言。CocoaChina 版主 “zenny_chen” 今天為我們帶來新的一篇 OpenCL 教程:變量地址限定符。

我們的示例程序是通過OpenCL來實現(xiàn)一個正方形的顏色漸變著色。這里,我們將牽涉到變量存儲屬性,另外還引入了向量數(shù)據(jù),向量數(shù)據(jù)是如何操作的,向量數(shù)據(jù)與標量數(shù)據(jù)是如何交叉操作的。

請先下載完整的工程文件 OpenCL_shading.zip (36 K) ,下面是 OpenCL 內(nèi)核代碼。

  1. // Render a square  
  2. // left-top:    red(1, 0, 0)  
  3. // left-bottom: green(0, 1, 0)  
  4. // right-top:   blue(0, 0, 1)  
  5. // right-bottom:black(0, 0, 0)  
  6.  
  7. __constant float4 left_top        = (float4)(1.0f, 0.0f, 0.0f, 0.0f);  
  8. __constant float4 left_bottom     = (float4)(0.0f, 1.0f, 0.0f, 0.0f);  
  9. __constant float4 right_top       = (float4)(0.0f, 0.0f, 1.0f, 0.0f);  
  10. __constant float4 right_bottom    = (float4)(0.0f, 0.0f, 0.0f, 0.0f);  
  11. __kernel void ColorShading(  
  12.                     __global float4 output[256][256]  
  13.                     )  
  14. {  
  15.     int dimX = get_global_id(0);  
  16.     int dimY = get_global_id(1);  
  17.     __local float4 deltaLeft = (left_top - left_bottom) / 255.0f;  
  18.     __local float4 deltaRight = (right_top - right_bottom) / 255.0f;  
  19.  
  20.     float4 left = left_bottom + deltaLeft * (float)dimY;  
  21.     float4 right = right_bottom + deltaRight * (float)dimY;  
  22.     float4 delta = (right - left) / 255.0f;  
  23.     float4 result = left + delta * (float)dimX;  
  24.  
  25. // clamp  
  26.     if(result.x > 1.0f)  
  27.         result.x = 1.0;  
  28.     if(result.y > 1.0f)  
  29.         result.y = 1.0f;  
  30.     if(result.x < 0.0f)  
  31.         result.x = 0.0f;  
  32.     if(result.y < 0.0f)  
  33.         result.y = 0.0f;  
  34.  
  35.     output[dimY][dimX] = result + (float4)(0.0f, 0.0f, 0.0f, 1.0f);  

我們首先來談?wù)勏蛄款愋?/p>

上述代碼中,我們引入了float4類型。它是一個向量類型。向量類型的定義規(guī)則是在基本類型后加n,n可以是2,4,8,16。比如:uchar8,float2,int16,long4等等。

而對于向量類型各分量的訪問,如果向量的分量個數(shù)在4個以內(nèi),我們可以依次用x,y,z,w來表示。這種標識法是與OpenGL Shader中的vertex shader對向量分量的訪問形式一樣。

另外,我們還可以用數(shù)值索引來訪問一個向量的各個分量。這個時候,我們可以將一個向量變量視為一個數(shù)組。如果向量的元素個數(shù)是16,那么第0到第9個元素分別用索引0到9表示;而第10到第15個元素,我們用a到f或A到F(即十六進制)來表示。而當我們用索引來表示的話,向量變量的.的后面必須跟一個字母 s。

下面舉些例子:

  1. int4 a = int4(1, 2, 3, 4); 

那么a.x是1;a.y是2;a.z是3;a.w是4。同樣,a.s0是1;a.s1是2;a.s2是3;a.s3是4。

對于向量變量,我們還能非常靈活地對其各個分量進行賦值。我們這里再引入一個swizzle的概念。swizzle是指可以對一個向量用另一個向量所對應(yīng)的任意元素進行賦值。比如說:

  1. int4 a = int4(1, 2, 3, 4);  
  2. int4 b = a.wzyx; 

這表示用a的第3個元素賦給b的第0個元素;a的第2個元素賦給b的第1個元素;用a的第1個元素賦給b的第2個元素;用a的第0個元素賦給b的第3個元素。然后,我們還能這么做:

  1. b.xz = a.s32; 

表示將a的第三個元素給b的第0個元素;a的第2個元素賦給b的第2個元素。是不是很靈活呢?呵呵。

向量變量之間的加、減、乘、除以及邏輯運算都是針對向量所對應(yīng)的各個分量進行的。比如說上面的int4 a; int4 b;a *= b; 相當于:a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w;

如果一個向量與一個標量進行計算,那么是將該標量與向量的沒個分量做相同的運算,比如:

  1. int4 a;  
  2. int i;  
  3. a *= i; 

相當于:a.x *= i; a.y *= i; a.z *= i; a.w *= i;

而i *= a;則是非法的。因此我們必須注意,在用向量與標量做算術(shù)邏輯操作時,必須把向量放在操作符的左邊,而標量要放在操作符的右邊。

上述代碼中:

  1. // clamp  
  2.     if(result.x > 1.0f)  
  3.         result.x = 1.0;  
  4.     if(result.y > 1.0f)  
  5.         result.y = 1.0f;  
  6.     if(result.x < 0.0f)  
  7.         result.x = 0.0f;  
  8.     if(result.y < 0.0f)  
  9.         result.y = 0.0f;  

這部分是分別對結(jié)果的r分量和g分量做飽和。那么這里,我們將引入一個OpenCL內(nèi)建函數(shù)來取代這些代碼。OpenCL內(nèi)建函數(shù)一般是GPU指 令集直接支持的,因此一個調(diào)用基本上只需要1條指令就能完成。所以我們在寫OpenCL時可以盡量使用內(nèi)建函數(shù)。當然,有些數(shù)學(xué)內(nèi)建函數(shù)為了效率會犧牲精 度,此時我們要自己判斷取舍。

我們接下去再介紹一個OpenCL的內(nèi)建函數(shù)——

  1. gentype clamp (gentype x, gentype minval,  
  2. gentype maxval) 

其語義是返回:fmin(fmax(x, minval), maxval),即對一個向量的每個分量取minval和maxval范圍內(nèi)的值。如果超出下界,那么取minval;如果超出上界,那么取maxval。

那么我再對OpenCL程序做次更新:

  1. // Render a square  
  2. // left-top:    red(1, 0, 0)  
  3. // left-bottom: green(0, 1, 0)  
  4. // right-top:   blue(0, 0, 1)  
  5. // right-bottom:black(0, 0, 0)  
  6.    
  7. __constant float4 left_top        = (float4)(1.0f, 0.0f, 0.0f, 0.0f);  
  8. __constant float4 left_bottom     = (float4)(0.0f, 1.0f, 0.0f, 0.0f);  
  9. __constant float4 right_top       = (float4)(0.0f, 0.0f, 1.0f, 0.0f);  
  10. __constant float4 right_bottom    = (float4)(0.0f, 0.0f, 0.0f, 0.0f);  
  11.    
  12. __constant float4 minValue = (float4)(0.0f, 0.0f, 0.0f, 0.0f);  
  13. __constant float4 maxValue = (float4)(1.0f, 1.0f, 1.0f, 0.0f);  
  14.    
  15. __kernel void ColorShading(  
  16.                     __global float4 output[256][256]  
  17.                     )  
  18. {  
  19.     int dimX = get_global_id(0);  
  20.     int dimY = get_global_id(1);  
  21.    
  22.     __local float4 deltaLeft = (left_top - left_bottom) / 255.0f;  
  23.     __local float4 deltaRight = (right_top - right_bottom) / 255.0f;  
  24.    
  25.     float4 left = left_bottom + deltaLeft * (float)dimY;  
  26.     float4 right = right_bottom + deltaRight * (float)dimY;  
  27.     float4 delta = (right - left) / 255.0f;  
  28.     float4 result = left + delta * (float)dimX;  
  29.    
  30.     // clamp  
  31.     result = clamp(result, minValue, maxValue);  
  32.    
  33.     output[dimY][dimX] = result + (float4)(0.0f, 0.0f, 0.0f, 1.0f);  

***,我們討論一下本文章的主題——變量的地址空間限定符

OpenCL有四種地址空間限定符——全局的(__global或global),本地的(__local或local),常量的(__constant或constant),私有的(__private或private)。

全局地址空間用于引用從全局存儲空間池所分配的存儲器對象。該存儲器對象可以聲明為指向一個標量的指針,指向一個向量的指針或用戶自定義的結(jié)構(gòu)的指針。這允許內(nèi)核程序讀或?qū)懺摼彺娴娜我馕恢?。這里要注意的是,__global(或global)所修飾的是指針變量所引用的地址。因此:

  1. __global long4 g;    // Error  
  2. __global image2d_t texture;    // OK. A 2D texture image  
  3.  
  4. void kernelMain(__global int *p    // OK  
  5.                              )  
  6. {  
  7.     __global float4 a;    // Error  

本地地址空間用于描述需要被分配在本地存儲空間的變量,并且能被一個工作組的所有工作項共享。該限定符可以被用于函數(shù)實參或在函數(shù)內(nèi)聲明的聲明的變量。而用于修飾函數(shù)實參時,變量必須是指針類型。

常量地址空間用于描述分配在全局存儲空間的變量,并且它們在內(nèi)核程序中是只讀的。這些全局只讀變量可以被所有工作組的所有工作項共享。
該限定符在可以用于修飾內(nèi)核函數(shù)的指針變量參數(shù),或是在內(nèi)核函數(shù)中修飾指針變量,或是作為全局變量。在本例中,我們把__constant修飾全局變量。
這里還要注意的是,由于__constant變量不能被寫,因此,作為全局變量時,它必須聲明后立即用常量初始化。這里的常量是指在編譯時能計算出數(shù)值結(jié)果的表達式。

私有地址空間的范圍很廣。所有函數(shù)參數(shù)、函數(shù)內(nèi)定義的局部變量都是私有的。因此我們往往可以省略掉__private關(guān)鍵字。

這里要注意的是OpenCL支持const關(guān)鍵字。這個關(guān)鍵字只在編譯時進行檢查,它所修飾的變量不能被修改,而對運行時該變量分配在哪個存儲空間無關(guān)。

***對這些關(guān)鍵字與實際性能的影像做一下簡單的介紹。當前流行的GPU等HPC流處理器采用分層的存儲架構(gòu)。全局存儲空間非常大(就相當于我們所說的顯存,目前最少也有128MB,俺的Mac Mini就是這個大?。菐捄馨嘿F,因此數(shù)據(jù)傳輸也是最慢的。

而第二層是局部存儲空間,或稱為本地存儲空間。局部存儲空間只能被一個工作組的所有工作項共享,并且每個工作組都有自己獨立的一個局部存儲空間。而每個局部存儲空間比較小,一般在128KB左右吧。但是其數(shù)據(jù)傳輸性能要比全局存儲器要大很多。

私有存儲空間是每個工作項私有的。也就是說每個工作項有自己獨立的私有存儲空間。這在GPU存儲架構(gòu)中實際上就是寄存器文件。寄存器文件比如一共 128KB,那么對所有工作項進行劃分的話,那么每個工作項能分到的存儲空間就非常小。但是寄存器的訪問是最快的,讀或?qū)懸淮沃恍枰?個周期。

小結(jié):蘋果開發(fā)語言OpenCL 變量地址限定符詳解的內(nèi)容介紹完了,希望本文對你有所幫助!

推薦一篇相關(guān)的文章:蘋果開發(fā)語言O(shè)penCL 多線程同步 附源碼

責(zé)任編輯:zhaolei 來源: CocoaChina
相關(guān)推薦

2011-07-20 10:50:19

蘋果 OpenCL 多線程

2011-06-20 13:54:41

Qt 動態(tài) 切換

2018-05-13 16:00:22

主播APP視頻

2020-02-12 14:03:29

網(wǎng)頁設(shè)計網(wǎng)頁游戲設(shè)計

2023-05-26 16:34:31

HBase數(shù)據(jù)模型

2011-09-13 17:03:16

Eclipse And

2021-10-29 08:19:54

JMeterJava java sample

2021-11-30 11:04:36

C++函數(shù)語言

2010-02-03 15:40:11

C++地址運算符

2011-08-05 10:01:23

Xcode Interface

2013-06-17 15:41:09

Windows PhoWP開發(fā)JSON生成C#類

2014-06-06 09:13:28

SwiftSwift編程

2014-07-09 09:13:16

Web效果Web特效

2010-09-17 09:34:29

開發(fā)工具Windows Pho

2024-05-15 08:54:04

C++類型限定符代碼

2011-04-12 15:03:26

C語言編程位操作

2010-11-09 09:51:52

匯編語言

2011-04-15 10:40:23

web開發(fā)框架

2010-10-25 09:54:09

Windows Pho

2013-12-06 10:43:52

Android 4.4特性
點贊
收藏

51CTO技術(shù)棧公眾號