0

在 C++ 中使用 VexCL 我试图计算向量中高于某个最小值的所有值,我想在设备上执行此计数。默认的 Reductors 仅提供 MIN、MAX 和 SUM 的方法,示例并没有非常清楚地显示如何执行这样的操作。此代码很慢,因为它可能在主机而不是设备上执行:

int amount = 0;
int minimum = 5;

for (vex::vector<int>::iterator i = vector.begin(); i != vector.end(); ++i)
{
    if (*i >= minimum)
    {
        amount++;
    }
}

我正在使用的向量将包含大量值,比如数百万个并且大部分是零。除了高于最小值的值的数量外,我还想检索包含这些值的向量 ID 列表。这可能吗?

4

2 回答 2

1

如果您只需要计算最小值以上的元素,这将很简单

vex::Reductor<int, vex::SUM> sum(ctx);
int amount = sum( vec >= minimum );

vec >= minimum表达式产生一系列 1 和 0,sum然后计算 1。

现在,由于您还需要获得高于最小值的元素的位置,所以它变得有点复杂:

#include <iostream>
#include <vexcl/vexcl.hpp>

int main() {
    vex::Context ctx(vex::Filter::Env && vex::Filter::Count(1));

    // Input vector
    vex::vector<int> vec(ctx, {1, 3, 5, 2, 6, 8, 0, 2, 4, 7});
    int n = vec.size();
    int minimum = 5;

    // Put result of (vec >= minimum) into key, and element indices into pos:
    vex::vector<int> key(ctx, n);
    vex::vector<int> pos(ctx, n);

    key = (vec >= minimum);
    pos = vex::element_index();

    // Get number of interesting elements in vec.
    vex::Reductor<int, vex::SUM> sum(ctx);
    int amount = sum(key);

    // Sort pos by key in descending order.
    vex::sort_by_key(key, pos, vex::greater<int>());

    // First 'amount' of elements in pos now hold indices of interesting
    // elements. Lets use slicer to extract them:
    vex::vector<int> indices(ctx, amount);

    vex::slicer<1> slice(vex::extents[n]);
    indices = slice[vex::range(0, amount)](pos);

    std::cout << "indices: " << indices << std::endl;
}

这给出了以下输出:

indices: {
    0:      2      4      5      9
}
于 2014-09-07T04:11:04.177 回答
0

@ddemidov

感谢您的帮助,它正在工作。但是,它比我将设备向量复制到主机并使用 Boost 排序的原始代码慢得多。下面是一些时间的示例代码:

#include <iostream>
#include <cstdio>
#include <vexcl/vexcl.hpp>
#include <vector>
#include <boost/range/algorithm.hpp>

int main()
{
    clock_t start, end;

    // initialize vector with random numbers
    std::vector<int> hostVector(1000000);
    for (int i = 0; i < hostVector.size(); ++i)
    {
        hostVector[i] = rand() % 20 + 1;
    }

    // copy to device
    vex::Context cpu(vex::Filter::Type(CL_DEVICE_TYPE_CPU) && vex::Filter::Any);
    vex::Context gpu(vex::Filter::Type(CL_DEVICE_TYPE_GPU) && vex::Filter::Any);
    vex::vector<int> vectorCPU(cpu, 1000000);
    vex::vector<int> vectorGPU(gpu, 1000000);
    copy(hostVector, vectorCPU);
    copy(hostVector, vectorGPU);

    // sort results on CPU
    start = clock();
    boost::sort(hostVector);
    end = clock();
    cout << "C++: " << (end - start) / (CLOCKS_PER_SEC / 1000) << " ms" << endl;

    // sort results on OpenCL
    start = clock();
    vex::sort(vectorCPU, vex::greater<int>());
    end = clock();
    cout << "vexcl CPU: " << (end - start) / (CLOCKS_PER_SEC / 1000) << " ms" << endl;

    start = clock();
    vex::sort(vectorGPU, vex::greater<int>());
    end = clock();
    cout << "vexcl GPU: " << (end - start) / (CLOCKS_PER_SEC / 1000) << " ms" << endl;

    return 0;
}

这导致:

C++: 17 ms
vexcl CPU: 737 ms
vexcl GPU: 1670 ms

使用 i7 3770 CPU 和(慢速)HD4650 显卡。正如我所读到的,OpenCL 应该能够对大顶点执行快速排序。您对如何使用 OpenCL 和 vexcl 执行快速排序有什么建议吗?

于 2014-09-08T11:00:40.473 回答