爲了編寫高效的代碼,您應該使用最簡單的數據類型。對於Renderscript來說更是如此,在內核中同樣的計算重複了很多次。現在,我想寫一個非常簡單的內核,其採用(顏色)的位圖作爲輸入並且產生一個int []數組作爲輸出:優化數據類型以提高速度
#pragma version(1)
#pragma rs java_package_name(com.example.xxx)
#pragma rs_fp_relaxed
uint __attribute__((kernel)) grauInt(uchar4 in) {
uint gr= (uint) (0.21*in.r + 0.72*in.g + 0.07*in.b);
return gr;
}
Java端:
int[] data1 = new int[width*height];
ScriptC_gray graysc;
graysc=new ScriptC_gray(rs);
Type.Builder TypeOut = new Type.Builder(rs, Element.U32(rs));
TypeOut.setX(width).setY(height);
Allocation outAlloc = Allocation.createTyped(rs, TypeOut.create());
Allocation inAlloc = Allocation.createFromBitmap(rs, bmpfoto1, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
graysc.forEach_grauInt(inAlloc,outAlloc);
outAlloc.copyTo(data1);
這需要40我的三星S5(5.0)和我的三星Tab2(4.2)180毫秒爲600k像素位圖。現在我試圖優化。由於輸出實際上是一個8位無符號整數(0-255),我試過如下:
uchar __attribute__((kernel)) grauInt(uchar4 in) {
uchar gr= 0.2125*in.r + 0.7154*in.g + 0.0721*in.b;
return gr;
}
,並在Java中改變4號線到:
Type.Builder TypeOut = new Type.Builder(rs, Element.U8(rs));
然而,這造成了錯誤「 32位整數源不匹配分配類型UNSIGNED_8「。我的解釋是,forEach_grauInt(inAlloc,outAlloc)語句在輸入和輸出端需要相同的Element-type。因此,我試圖«disconnecd»入點和出分配和考慮投入分配(位圖)作爲一個全局變量bmpAllocIn如下:
#pragma version(1)
#pragma rs java_package_name(com.example.dani.oldgauss)
#pragma rs_fp_relaxed
rs_allocation bmpAllocIn;
int32_t width;
int32_t height;
uchar __attribute__((kernel)) grauInt(uint32_t x, uint32_t y) {
uchar4 c=rsGetElementAt_uchar4(bmpAllocIn, x, y);
uchar gr= (uchar) 0.2125*c.r + 0.7154*c.g + 0.0721*c.b;
return gr;
}
隨着Java方面:
int[] data1 = new int[width*height];
ScriptC_gray graysc;
graysc=new ScriptC_gray(rs);
graysc.set_bmpAllocIn(Allocation.createFromBitmap(rs,bmpfoto1));
Type.Builder TypeOut = new Type.Builder(rs, Element.U8(rs));
TypeOut.setX(width).setY(height);
Allocation outAlloc = Allocation.createTyped(rs, TypeOut.create());
graysc.forEach_grauInt(outAlloc);
outAlloc.copyTo(data1);
現在令人驚訝的是,我再次得到相同的錯誤消息:「32位整數源不匹配分配類型UNSIGNED_8」。這我不明白。我在這裏做錯了什麼?
哇,謝謝。出於某種奇怪的原因,我總是與Int []數組一起工作,因爲我認爲Byte []是有符號的(-127-128),但我看到Byte []是靈活的...聰明!所以,這簡直令人難以置信:速度通過改變到正確的類型而增加了一倍。本課有一個諷刺意味的是,在提出這個問題時,我沒有記住REAL類型不匹配不在內核內,而是在copyTo語句內。非常感謝,非常感謝! – Settembrini
關於附註:「它會提高某些架構的性能。」 - >你的意思是,該整數應該是浮動的首選,這不是因爲大小(兩者都是32位),而是因爲浮點計算本質上比整數計算效率低,對嗎? – Settembrini
它確實取決於體系結構。在許多GPU上,FP操作與整數一樣快(或快),在這種特殊情況下,整數版本還需要一個操作(分割或位移),所以它可能會變慢。但是,如果你的目標是舊的,功能較差的設備,RS可能被編譯爲在CPU上運行,那麼整數操作可以爲你提供優勢。如果性能對您的應用來說非常重要,那麼您可以發佈兩個版本,並決定在運行時使用哪一個(基於時間點)。 –