首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何优化该循环的计算速度?

如何优化该循环的计算速度?
EN

Stack Overflow用户
提问于 2015-03-28 23:42:44
回答 2查看 170关注 0票数 3

我被一个难题困住了(至少对我来说是这样)。在分析我的代码时,我注意到几乎所有(单核心)计算时间都被下面的单个嵌套循环(图像上的双积分)所占用。你认为加速计算的最好方法是什么?

我试图将它映射到嵌套流,但我不知道如何映射多个if块.尝试在GPU上使用OpenCL来解决这个问题更合适吗?

ip是一个ImageJ ImageProcessor,它的方法.getPixelValue(x,y)也很消耗资源。但是,由于它属于一个已建立的库,如果可以的话,我想避免修改它。

变量声明:

代码语言:javascript
复制
private ImageProcessor ip = null; //This type comes from ImageJ
private double area;
private double a11, a22;
private double u1, u2;
private double v1, v2;
private double y1, y2;
private static final double HALF_SQRT2 = sqrt(2.0) / 2.0;
private static final double SQRT_TINY =
    sqrt((double)Float.intBitsToFloat((int)0x33FFFFFF));

功能:

代码语言:javascript
复制
private double contrast (
) {
    if (area < 1.0) {
        return(1.0 / SQRT_TINY);
    }
    double c = 0.0;
    final int xmin = max((int)floor(u1), 0);
    final int xmax = min((int)ceil(v1), width - 1);
    final int ymin = max((int)floor(u2), 0);
    final int ymax = min((int)ceil(v2), height - 1);
    if ((u1 < xmin) || (xmax < v1) || (u2 < ymin) || (ymax < v2)){
        return(1.0 / SQRT_TINY);
    }
    if ((xmax <= xmin) || (ymax <= ymin)) {
        return(1.0 / SQRT_TINY);
    }
    for (int y = ymin; (y <= ymax); y++) {
        final double dy = y2 - (double)y;
        final double dy2 = dy * dy;
        for (int x = xmin; (x <= xmax); x++) {
            final double dx = y1 - (double)x;
            final double dx2 = dx * dx;
            final double d = sqrt(dx2 + dy2);
            double z = a11 * dx2 + a12 * dx * dy + a22 * dy2;
            if (z < SQRT_TINY) {
                c -= ip.getPixelValue(x, y);
                continue;
            }
            z = a3 / sqrt(z);
            double d0 = (1.0 - z / SQRT2) * d;
            if (d0 < -HALF_SQRT2) {
                c -= ip.getPixelValue(x, y);
                continue;
            }
            if (d0 < HALF_SQRT2) {
                c += SQRT2 * d0 * ip.getPixelValue(x, y);
                continue;
            }
            d0 = (1.0 - z) * d;
            if (d0 < -1.0) {
                c += ip.getPixelValue(x, y);
                continue;
            }
            if (d0 < 1.0) {
                c += (1.0 - d0) * ip.getPixelValue(x, y) / 2.0;
                continue;
            }
        }
    }
    return(c / area);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-29 18:30:27

您可以尝试一种划分和征服方法。

将图像划分为n部件,这些部件被并行处理。但是,您必须处理边界上发生的边缘情况(两个部分在边界上相遇)。

或者你可以开始寻找计算(离散)积分的数值算法,这些算法是为并行性设计的。

更新

因为您的方法名为contrast,所以我假设您正在更改图像的对比度。

对图像的操作可以通过卷积(本质上是一个离散的双积分,如果在2D图像上执行)与特定的内核 (图像滤波器)来执行。这些操作可以在GPU上计算,并产生数量级的加速.您可以使用OpenCl编写在多个GPU上执行的程序。

票数 4
EN

Stack Overflow用户

发布于 2015-03-29 04:32:20

您没有提供太多关于循环中发生的事情的信息,例如,变量'ip‘是什么。但是通常,我建议实例化for-循环范围之外的变量,因为使用局部变量会增加内存使用量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29323956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档