【问题标题】:VexCL: count amount of values in a vector above minimumVexCL:计算向量中高于最小值的值的数量
【发布时间】:2014-09-05 10:54:29
【问题描述】:

在 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 列表。这可能吗?

【问题讨论】:

  • 我不了解 VexCL,但在主机端,您可能应该使用 count_if 而不是自己循环。 VexCL 没有类似的东西吗?

标签: c++ vector count vexcl


【解决方案1】:

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

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

vec &gt;= 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
}

【讨论】:

    【解决方案2】:

    @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 执行快速排序有什么建议吗?

    【讨论】:

    • 您不应该测量对vex::sort() 的第一次调用(在两个设备上),因为它包括 OpenCL 编译开销。这是您修改后的源的链接:gist.github.com/ddemidov/cf141c97aa22de32c22d,这会产生以下输出:CPU:Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz (Intel(R) OpenCL) GPU:Tesla K40c (NVIDIA CUDA) ) C++:34 毫秒 vexcl CPU:281 毫秒 vexcl GPU:1 毫秒
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 2014-09-13
    • 2015-10-11
    • 1970-01-01
    • 2022-11-12
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多