- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要对元组数组进行排序,因此我正在为元组定义一个运算符并使用 thrust::sort
进行排序。
所以我发现,对元组数组进行排序比对数字数组进行排序要慢得多。这是我的代码:
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/set_operations.h>
#include <thrust/reduce.h>
#include <thrust/unique.h>
#include <thrust/binary_search.h>
#include <thrust/gather.h>
#include <thrust/transform.h>
#include <thrust/functional.h>
#include <thrust/sort.h>
#include <thrust/execution_policy.h>
#include <iostream>
static const int size = 100000;
#define mzi(x) thrust::make_zip_iterator(x)
#define mt(...) thrust::make_tuple(__VA_ARGS__)
typedef thrust::tuple<int, int> IntTuple;
typedef thrust::device_vector<IntTuple>::iterator TupleIterator;
typedef thrust::device_vector<int>::iterator IntIterator;
typedef thrust::tuple<IntIterator, IntIterator> IteratorTuple;
typedef thrust::zip_iterator<IteratorTuple> ZipIterator;
struct TupleComp
{
__host__ __device__
bool operator()(const IntTuple& t1, const IntTuple& t2)
{
return t1.get<0>() != t2.get<0>() ? t1.get<0>() < t2.get<0>() : t1.get<1>() > t2.get<1>();
}
};
int main()
{
timespec start;
clock_gettime(0, &start);
thrust::device_vector<int> dataA1(size);
thrust::device_vector<int> dataA2(size);
thrust::device_vector<int> dataB1(size);
thrust::device_vector<int> dataB2(size);
srand(time(NULL));
for (int i = 0; i < size; i++)
{
//dataA[i] = dataA[i - 1] + (rand() % 100);
dataA1[i] = (rand() % 100);
dataA2[i] = (rand() % 100);
dataB1[i] = (rand() % 100);
dataB2[i] = (rand() % 100);
std::cout << dataA1[i] << "\t" << dataA2[i] << "\t" << dataB1[i] << "\t" << dataB2[i];
std::cout << std::endl;
}
timespec end;
clock_gettime(0, &end);
std::cout << "gendb took: " << end.tv_sec - start.tv_sec << "s" << end.tv_nsec - start.tv_nsec << "ns" << std::endl;
ZipIterator beginA = mzi(mt(dataA1.begin(), dataA2.begin()));
ZipIterator beginB = mzi(mt(dataB1.begin(), dataB2.begin()));
ZipIterator endA = mzi(mt(dataA1.end(), dataA2.end()));
ZipIterator endB = mzi(mt(dataB1.end(), dataB2.end()));
thrust::device_vector<IntTuple> A(size);
thrust::device_vector<IntTuple> B(size);
clock_gettime(0, &start);
thrust::copy(beginA, endA, A.begin());
thrust::copy(beginB, endB, B.begin());
clock_gettime(0, &end);
std::cout << "thrust::copy took: " << end.tv_sec - start.tv_sec << "s" << end.tv_nsec - start.tv_nsec << "ns" << std::endl;
clock_gettime(0, &start);
thrust::sort(A.begin(), A.end());
clock_gettime(0, &end);
std::cout << "A thrust::sort took: " << end.tv_sec - start.tv_sec << "s" << end.tv_nsec - start.tv_nsec << "ns" << std::endl;
clock_gettime(0, &start);
thrust::sort(B.begin(), B.end(), TupleComp());
clock_gettime(0, &end);
std::cout << "B thrust::sort took: " << end.tv_sec - start.tv_sec << "s" << end.tv_nsec - start.tv_nsec << "ns" << std::endl;
clock_gettime(0, &start);
thrust::sort(dataA1.begin(), dataA1.end());
clock_gettime(0, &end);
std::cout << "regular thrust::sort took: " << end.tv_sec - start.tv_sec << "s" << end.tv_nsec - start.tv_nsec << "ns" << std::endl;
clock_gettime(0, &start);
thrust::sort(beginA, endA, TupleComp());
thrust::sort(beginB, endB, TupleComp());
clock_gettime(0, &end);
std::cout << "thrust::sort took: " << end.tv_sec - start.tv_sec << "s" << end.tv_nsec - start.tv_nsec << "ns" << std::endl;
}
我发现元组排序比常规排序慢 ~10 倍。
我不明白为什么。推力排序的复杂度直接受操作者影响吗?尽管如此,我的运算符并不比常规比较器慢 10 倍。
注意:它不仅慢了 10 倍:对于 100000,它慢了 ~10 倍对于 1000000,它慢了约 20 倍
我还发现,将两个数组处理成一个元组数组并对该数组进行排序的速度提高了大约 150%,而 thrust::copy 几乎什么都不做(1M 为 0.3)。
注2:
我将我的运算符更改为:
struct TupleComp
{
__host__ __device__
bool operator()(const IntTuple& t1, const IntTuple& t2)
{
if(t1.get<0>() < t2.get<0>())
return true;
if(t1.get<0>() > t2.get<0>())
return false;
return t1.get<1>() > t2.get<1>();
}
};
现在排序速度提高了大约 112.5%,这可能是因为第一个值的 equals
很少发生,这样就可以减少 if
的检查一般在运营商中。
最佳答案
抱歉,Nsight 完全让我困惑,一直以来我都认为我处于 Release模式,但它自己的运行配置设置为运行 Debug模式。
现在我已经确定一切都准备好发布了,而且它运行得更好。
int 排序和元组排序之间的差异只有 ~150%,这更有意义。不确定我还能做些什么来提高性能,但它已经足够好了。
结论是:小心使用 eclipse 首选项,尤其是在 linux 上。
关于c++ - 元组上的推力排序非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21109582/
我需要一些帮助来追踪 thrust::fill 给我的编译错误。 代码没有问题: line 9 #include // needed for other thrus
如何使用推力返回事件数组元素的索引,即返回数组元素等于 1 的索引向量? 对此进行扩展,在给定数组维度的多维索引的情况下,这将如何工作? 编辑:目前该功能看起来像这样 template void Vo
当尝试创建thrust::device_vector的struct时,我得到了Bus error (core dumped)。奇怪的是,下面的代码在我的笔记本电脑(Quadro P2000)上运行良好
我尝试将数据从主机复制到设备并返回,但不是使用 CUDA API,而是使用推力库。我在 thrust::host_vector 中分配了内存,并尝试将其复制到 thrust::device_vecto
我有一对大小相等的数组,我将它们称为键和值。 例如: K: V 1: 99 1: 100 1: 100 1: 100 1: 103 2: 103 2: 105 3: 45 3: 67 键被排序,与每个
我想知道是否可以使用 Thrust 库按键排序,而无需创建 Vector 来存储键(动态)。例如,我有以下两个 vector :键和值: vectorKeys: 0, 1, 2, 0,
假设我想做一个 thrust::reduce_by_key 但我不关心输出键是什么。有没有一种方法可以通过某种方式将空对象(可能是空指针)传递给该参数的算法,从而不会创建毫无意义的输出键列表,从而节省
我目前正在通过以下方式按键对值进行排序 thrust::sort_by_key(thrust::device_ptr(keys), thrust::device
这个问题在这里已经有了答案: is there a better and a faster way to copy from CPU memory to GPU using thrust? (1 个回
有没有办法在不实际分配 vector 的情况下声明推力 vector 指针?我需要将此指针用作类中的成员变量。因为我事先并不知道 vector 的大小,所以我不能将 vector 静态分配为成员变量。
我想知道如何 thrust::set_intersection有效,但从我的测试结果来看,我对这个函数的作用更加困惑。 举几个例子: const int size1 = 5; const int si
考虑以下数据集和质心。一共有7个人,两个均值有8个维度。它们按行主要顺序存储。 short dim = 8; float centroids[] = { 0.223, 0.002, 0.223
我有以下(可编译和可执行)代码,使用 CUDA Thrust 来执行 float2 数组的缩减。它工作正常 using namespace std; // includes, system #incl
我有一个使用 Thrust 目前在单个 GPU 上正常工作的 Cuda C++ 代码。我现在想为多 GPU 修改它。我有一个主机函数,其中包括许多对设备数组进行排序、复制、计算差异等的推力调用。我想使
我在 thrust::device_vector 中有一个矩阵(面向行) .有什么方法可以获取该 vector 的切片/ View (也属于 thrust::device_vector 类型)?我对复
我遇到了 thrust 库的 reduce_by_key 函数的问题。对我来说这看起来像是一个错误,但我想在报告之前确定一下。 首先,我的设置:CUDA 7.0、Windows 8、NIVIDA Ge
我有以下函数,用于用从 -time/2 到 time/2 的步长和步长 dt 填充 vector t: #define THRUST_PREC thrust::complex __host__ voi
在我现在正在编写的程序中,我想使用 GPU 或 CPU 进行计算(用于对彼此进行基准测试)。为此,我想要一些通用指针,我可以像这样使用 device_vector 或 host_vector 的实例对
我试图找到数组中的最小元素: thrust::device_ptr devPtr(d_ary); int minPos = thrust::min_element(devPtr.begin(),
我的计划是使用 Pearsons 相关性计算距离矩阵,并从距离矩阵中为每个节点 (q=ln(n)) 获取 q-最近邻,并将它们放入结果向量中。我在 C++ 中使用相关函数循环内的 STL 优先级队列来
我是一名优秀的程序员,十分优秀!