如何从稀疏数组表示到CUDA中的密集表示

时间:2016-01-23 22:36:47

标签: c++ arrays cuda thrust

我是CUDA的初学者,并试图找出最有效的方法。

我有一系列值。我想构建一个数组,该数组基本上是每个值出现在数组中的次数。有没有一种有效的算法来使用CUDA来做到这一点?

例如,我们假设值的范围是0-10。实际上我也有负值,但我需要忽略它们。 (编辑:我已经试过了推力:: remove_if,然后是推力:: reduce_by_key,但是我在寻找能够忽略我不关心的元素方面的效率更高的东西几乎像一个推力:: reduce_by_key_if)。该列表远小于值的范围(即,绝大多数值超出我关注的范围)。我可能有:

int32_t values[5] = {3, 5, 2, 5, 1, -1};

我想构建数组:

int32_t result[10] = {0, 1, 1, 1, 0, 2, 0, 0, 0, 0};

现在我主要是在CPU上做这件事。我尝试使用推力对索引列表进行排序,以提高内存缓存性能,但性能改进最多只是微不足道。

有什么想法?是否有一种优雅的方式来做到这一点?

2 个答案:

答案 0 :(得分:2)

您可以修改thrust histogram example,以便在排序后构建直方图时仅考虑非负值:

#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/copy.h>
#include <thrust/adjacent_difference.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/find.h>
#include <thrust/functional.h>
#include <thrust/binary_search.h>

#include <iostream>
#include <iomanip>
#include <iterator>

#include <cstdint>

template <typename Vector>
void print_vector(const std::string& name, const Vector& v)
{
  typedef typename Vector::value_type T;
  std::cout << "  " << std::setw(20) << name << "  ";
  thrust::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, " "));
  std::cout << std::endl;
}

int main(void)
{

  const std::int32_t N = 6;

  std::int32_t values[6] = {3, 5, 2, 5, 1, -1};

  thrust::device_vector<std::int32_t> d_values(values, values + N);

  print_vector("initial data", d_values);

  // sort values to bring equal elements together
  thrust::sort(d_values.begin(), d_values.end());

  print_vector("sorted data", d_values);

  using thrust::placeholders::_1;
  auto first_non_negative = thrust::find_if(d_values.begin(), d_values.end(), _1>=0);

  // number of histogram bins is equal to the maximum value plus one
  std::int32_t num_bins = d_values.back() + 1;

  thrust::device_vector<std::int32_t> histogram(num_bins);

  thrust::counting_iterator<std::int32_t> search_begin(0);
  thrust::upper_bound(first_non_negative, d_values.end(),
                      search_begin, search_begin + num_bins,
                      histogram.begin());

  thrust::adjacent_difference(histogram.begin(), histogram.end(),
                              histogram.begin());

  print_vector("histogram", histogram);

  return 0;
}

<强>输出

initial data  3 5 2 5 1 -1 
sorted data  -1 1 2 3 5 5 
histogram     0 1 1 1 0 2 

答案 1 :(得分:0)

thrust :: remove_if后跟thrust :: reduce_by_key最终成为我应用程序的最佳方式。