【问题标题】:PixelSorting with Renderscript使用 Renderscript 进行像素排序
【发布时间】:2020-04-10 18:58:00
【问题描述】:

我用纯java做了一个小像素排序应用程序,效果很好,但是性能很差。我听说 renderscript 就是为了这个!

我编写了一些代码,但 C99 太新了,所以我知道缺少一些东西。我做了这个小测试脚本。

#pragma version(1)
#pragma rs java_package_name(com.simahero.pixelsort)
#pragma rs_fp_relaxed

float treshhold = 0.f;

static void swap(uchar4 *xp, uchar4 *yp)
{
    uchar4 temp = *xp;
    *xp = *yp;
    *yp = temp;
}

static void selectionSort(uchar4 arr[], int n)
{
    int i, j, min_idx;

    for (i = 0; i < n-1; i++)
    {
        min_idx = i;
        for (j = i+1; j < n; j++)
        if (arr[j].r < arr[min_idx].r)
            min_idx = j;

        swap(&arr[min_idx], &arr[i]);
    }
}

rs_allocation RS_KERNEL invert(rs_allocation in) {

    for (int i = 0; i < rsAllocationGetDimY(in); i++){
        uchar4 row[rsAllocationGetDimX(in)];
        for (int j = 0; j < rsAllocationGetDimX(in); j++){
            uchar4 pixel = rsGetElementAt_uchar4(in, i, j);
            row[j] = pixel;
        }
        selectionSort(row, rsAllocationGetDimX(in));
     }
  return in;
}

void process(rs_allocation inputImage, rs_allocation outputImage) {
   outputImage = invert(inputImage);
}

我只是在异步任务中调用它,但是位图是空的,或者我不知道,因为缺乏调试 rs 的知识。

script.invoke_process(mInAllocation, outputAllocation);
outputAllocation.copyTo(bo);

【问题讨论】:

    标签: android performance renderscript android-renderscript


    【解决方案1】:

    您正在复制图像的每一行,然后对其进行排序,但您永远不会写回结果(没有在任何地方调用 rsSetElement 方法)。即使你这样做了,它也不认为你会用这种方法获得令人满意的表现。我会通过编写一个在输入分配的所有行上执行的内核来解决这个问题(查看 Renderscirpt 内核的 LaunchOptions),因此它将至少在所有行上并行执行。看起来像:

    rs_allocation allocIn;
    rs_allocation allocOut;
    
    void RS_KERNEL sortRows(uchar4 in, int x, int y){
        //with proper launch options, x stays always the same, while this kernel gets called in parallel for all rows of the input allocation ( = different y values)
        for (int currentCollumn = 0; currentCollumn  < rsAllocationGetDimX(allocIn); currentCollumn ++){
           //do your stuff for this row (by using y as index). Use rsGetElementAt and rsSetElementAt calls only (avoid copies for speed)   
        }
     }
    

    【讨论】:

    • 我可能会误解一些东西,但是阅读启动选项,内核将使用定义的坐标处理子图像。如果是这样,我应该循环 tru Java 代码中的每一行,这将使其非并行。正如这里的文档中提到的:developer.android.com/guide/topics/renderscript/… 我可以做一个单源脚本并在其中循环 tru,不是吗?
    • ``` public void createScript() { rs = RenderScript.create(this);分配在 = Allocation.createFromBitmap(rs, bitmap);分配出 = Allocation.createTyped(rs, in.getType()); Script.LaunchOptions options = new Script.LaunchOptions(); options.setY(0, 1); Horizo​​ntalSort = new ScriptC_horizo​​ntalSort(rs); Horizo​​ntalSort.set_allocIn(in); Horizo​​ntalSort.set_allocOut(out); Horizo​​ntalSort.forEach_sortRows(in, options); } } ```
    • 如果你想循环 y,你应该使用 options.setX(0,1) 作为启动选项(这会冻结你内核所有调用的 x 位置)。然后,forEach_sortRows() 调用将为每个行执行内核(在 cpu 或 gpu 上并行)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多