优化数据类型以提高速度

时间:2015-08-14 17:29:40

标签: types allocation renderscript

为了编写有效的代码,您应该使用最简单的数据类型。对于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);

对于600k像素的位图,我的三星S5(5.0)需要40毫秒,而我的三星Tab2(4.2)需要180毫秒。现在我试着优化。由于输出实际上是一个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。因此,我尝试“断开”in-out-out-Allocation并将输入分配(bitmap)视为全局变量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不匹配”。这个我无法理解。我在这做错了什么?

1 个答案:

答案 0 :(得分:1)

原因是

int[] data1 = new int[width * height];

线。您正在尝试使用它创建的数组作为copyTo()的目标,并抛出异常。将其更改为

byte[] data1 = new byte[width * height];

一切都会好的。 BTW,输入和输出分配可以是不同类型的。

作为旁注,您还可以完全消除RS过滤器的浮点计算,它将提高某些体系结构的性能。