为了编写高效的代码,您应该使用最简单的数据类型。对于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上运行,那么整数操作可以为你提供优势。如果性能对您的应用来说非常重要,那么您可以发布两个版本,并决定在运行时使用哪一个(基于时间点)。 –