4

我想尽快找到矩阵的非零元素。考虑到CUDA\ Jacket,我了解到这比“常规” CPU 版本Matlab的 find 慢得多,这可能是由于内存分配问题,因为在 find 函数之前输出的大小是未知的。但是,使用bwlabeland regionprops(两者都在 中支持Jacket)确实有效地产生了有关非零元素的信息,并且比Matlab内置的 Image Processing Toolbox 函数快得多。有没有办法利用它来获得非零元素?有没有办法对使用找到的每个标记对象进行一些处理bwlabel

4

2 回答 2

2

以我的经验,Jacket 支持的 FIND 实现非常快,至少对于大于 300x300 左右的矩阵。我在笔记本电脑上对此进行了测试,并在下面分享了结果。我的硬件规格是:

>> ginfo
Jacket v2.2 (build 77be88c) by AccelerEyes (64-bit Windows)
License: Standalone (C:\Program Files\AccelerEyes\Jacket\2.2\engine\jlicense.dat)
Addons: MGL16, JMC, SDK, DLA, SLA
CUDA toolkit 4.2, driver 4.2 (296.10)
GPU1 GeForce GT 540M, 2048 MB, Compute 2.1 (single,double)
Display Device: GPU1 GeForce GT 540M
Memory Usage: 1697 MB free (2048 MB total)

CPU是英特尔酷睿i7-2630QM。

我知道夹克在 CPU 上的 FIND 功能上达到了约 3 倍的加速。这是我使用的基准代码:

% time Jacket vs CPU
for n = 5:12;
    x(n) = 2^n;
    Ac = single(rand(x(n)));
    Ag = gsingle(Ac);
    t_cpu(n) = timeit(@() find(Ac > 0.5));
    t_gpu(n) = timeit(@() find(Ag > 0.5));
end

% plot results
plot(x, t_cpu ./ t_gpu);
xlabel('Matrix Edge Size', 'FontSize', 14);
ylabel('Jacket (GPU) Speedup over CPU', 'FontSize', 14);

以下是运行此代码的结果:

夹克 (GPU) 对 CPU 的加速

我确信 Jacket 支持的 BWLABEL 和 REGIONPROPS 函数也非常快,但是在上面的基准测试中,您可能可以使用 FIND 本身。

于 2012-08-25T21:50:08.390 回答
1

除了 arrayfire 讨论的之外,另一种可能性是使用 CUDA Thrust。下面,我将发布一个简单的示例,其中根据(x, y)阈值选择 2D 域上的粒子。我应该很容易适应海报感兴趣的情况,或者更一般地说,模拟Matlab's的行为find

代码

#include <thrust/gather.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/functional.h>
#include <thrust/copy.h>
#include <thrust/device_vector.h>
#include <iostream>

struct isWithinThreshold {

    double2 thresholdPoint;

    __host__ __device__ isWithinThreshold(double2 thresholdPoint_) { thresholdPoint = thresholdPoint_; };

    __host__ __device__ bool operator()(const double2 r) {
        return ((r.x > thresholdPoint.x) && (r.y > thresholdPoint.y));
    }
};

/********/
/* MAIN */
/********/
int main()
{
    const int N = 5;
    double2 thresholdPoint = make_double2(0.5, 0.5);

    thrust::host_vector<double2> particleCoordinates(N);
    particleCoordinates[0].x = 0.45;    particleCoordinates[0].y = 0.4;
    particleCoordinates[1].x = 0.1;     particleCoordinates[1].y = 0.3;
    particleCoordinates[2].x = 0.8;     particleCoordinates[2].y = 0.9;
    particleCoordinates[3].x = 0.7;     particleCoordinates[3].y = 0.9;
    particleCoordinates[4].x = 0.7;     particleCoordinates[4].y = 0.45;

    // --- Find out the indices
    thrust::host_vector<int> indices(N);
    thrust::host_vector<int>::iterator end = thrust::copy_if(thrust::make_counting_iterator(0),
        thrust::make_counting_iterator(N),
        particleCoordinates.begin(),
        indices.begin(),
        isWithinThreshold(thresholdPoint));
    int size = end - indices.begin();
    indices.resize(size);

    // --- Fetch values corresponding to the selected indices
    thrust::host_vector<double2> values(size);
    thrust::copy(thrust::make_permutation_iterator(particleCoordinates.begin(), indices.begin()),
        thrust::make_permutation_iterator(particleCoordinates.end(), indices.end()),
        values.begin());

    for (int k = 0; k < size; k++)
        printf("k = %d; index = %d; value.x = %f; value.y = %f\n", k, indices[k], values[k].x, values[k].y);

    return 0;
}
于 2018-07-30T05:06:58.950 回答