我有10个数组。我想对它们进行排序。但是由于它们的元素具有相同的行为,所以我想保存计算并仅对其中的一个进行排序,而其他元素将基于已排序的数组进行排序。 我正在用推力。 有一个最佳的原因吗? 预先谢谢你。
答案 0 :(得分:1)
从评论中,我的建议是:
在第一个数据集(数组)上使用thrust::sort_by_key
,将第一个数据集作为键,并将索引序列(0、1、2,...)作为值。然后在推力聚集或分散操作中使用重新排列的索引序列来重新排列其余的数组。
根据要求,这是一个可行的示例:
$ cat t282.cu
#include <thrust/sort.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/copy.h>
#include <thrust/sequence.h>
#include <iostream>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/iterator/zip_iterator.h>
const size_t ds = 5;
typedef float ft;
int main(){
ft a1[ds] = {0.0f, -3.0f, 4.0f, 2.0f, 1.0f};
// data setup
thrust::device_vector<ft> d_a1(a1, a1+ds);
thrust::device_vector<ft> d_a2(ds);
thrust::device_vector<ft> d_a3(ds);
thrust::device_vector<ft> d_a2r(ds);
thrust::device_vector<ft> d_a3r(ds);
thrust::device_vector<size_t> d_i(ds);
thrust::sequence(d_i.begin(), d_i.end());
thrust::sequence(d_a2.begin(), d_a2.end());
thrust::sequence(d_a3.begin(), d_a3.end());
// sort
thrust::sort_by_key(d_a1.begin(), d_a1.end(), d_i.begin());
// copy, using sorted indices
thrust::copy_n(thrust::make_permutation_iterator(thrust::make_zip_iterator(thrust::make_tuple(d_a2.begin(), d_a3.begin())), d_i.begin()), ds, thrust::make_zip_iterator(thrust::make_tuple(d_a2r.begin(), d_a3r.begin())));
// output results
thrust::host_vector<ft> h_a1 = d_a1;
thrust::host_vector<ft> h_a2 = d_a2r;
thrust::host_vector<ft> h_a3 = d_a3r;
std::cout << "a1: " ;
thrust::copy_n(h_a1.begin(), ds, std::ostream_iterator<ft>(std::cout, ","));
std::cout << std::endl << "a2: " ;
thrust::copy_n(h_a2.begin(), ds, std::ostream_iterator<ft>(std::cout, ","));
std::cout << std::endl << "a3: " ;
thrust::copy_n(h_a3.begin(), ds, std::ostream_iterator<ft>(std::cout, ","));
std::cout << std::endl;
}
$ nvcc -o t282 t282.cu
$ cuda-memcheck ./t282
========= CUDA-MEMCHECK
a1: -3,0,1,2,4,
a2: 1,0,4,3,2,
a3: 1,0,4,3,2,
========= ERROR SUMMARY: 0 errors
$
在这里,代替thrust::gather
或thrust::scatter
操作,我只是用thrust::copy_n
进行了thrust::permutation_iterator
,以实现重新排序。我将其余的数组组合在一起,以使用thrust::zip_iterator
重新排序,但这不是唯一的方法。
请注意,我不是针对10个数组,而是针对3个数组,但这应该说明了该方法。扩展到10个阵列应该仅仅是机械的。但是请注意,由于thrust::tuple
限于10个项目,因此必须对10-11个以上的数组进行一些修改。作为修改,您可以简单地循环调用thrust::copy_n
,对每个数组重新排序一次,而不用使用zip_iterator
。我认为这不会在效率上产生很大的差异。
答案 1 :(得分:0)
执行此操作的几种方法(与Thrust无关):
indices
至0, 1, 2, 3...
等的数组。indices
,比较功能是访问数组之一(比较最便宜的数组)中的元素,然后进行比较。调用结果数组arr
都应用Gather操作,该操作使用排序后的indices
和arr
作为收集数据。即所有sorted_arr[i] = arr[indices[i]]
的{{1}}。
让i
是用于排序(或比较元素)的最便宜的数组
cheap
对的数组。pairs[i] = { i, cheap[i] }
pairs
投影到其第一个元素上:pairs
indices[i] = pairs[i].first
投影到第二个元素:pairs
第二个选项应该是最快的,但需要更多的精力;加上推力,这可能很困难。第一个或第三个应该是最简单的;推力接受自定义比较器,对吗?如果没有,则可能必须使用适当的比较器来定义包装器类。