推力:sort_by_key 与 zip_iterator 性能
Posted
技术标签:
【中文标题】推力:sort_by_key 与 zip_iterator 性能【英文标题】:Thrust: sort_by_key with zip_iterator performance 【发布时间】:2011-08-10 19:58:45 【问题描述】:问题
我正在使用 sort_by_key
并使用 zip_iterator
传递值。这个sort_by_key
被调用了很多次,经过一定的迭代,它变成了10x 慢! 性能下降的原因是什么?
症状
我正在使用sort_by_key
对 3 个向量进行排序,其中一个作为关键向量:
struct Segment
int v[2];
;
thrust::device_vector<int> keyVec;
thrust::device_vector<int> valVec;
thrust::device_vector<Segment> segVec;
// ... code which fills these vectors ...
thrust::sort_by_key( keyVec.begin(), keyVec.end(),
make_zip_iterator( make_tuple( valVec.begin(), segVec.begin() ) ) );
向量的大小通常在 400 万左右。在最初的 2 次调用中,sort_by_key
需要 0.04 秒,在循环 3 中需要 0.1 秒,然后在其余循环中进一步降级到 0.3 秒。因此,我们看到性能下降了 10 倍。
额外信息
为了确保唯一的降级因素是sort_by_key
,我将上面的内容替换为使用手写内核的手动排序:
thrust::device_vector<int> indexVec( keyVec.size() );
thrust::sequence( indexVec.begin(), indexVec.end() );
// Sort the keys and indexes
thrust::sort_by_key( keyVec.begin(), keyVec.end(), indexVec.begin() );
thrust::device_vector<int> valVec2( keyVec.size() );
thrust::device_vector<Segment> segVec2( keyVec.size() );
// Use index array and move vectors to destination
moveKernel<<< x, y >>>(
toRawPtr( indexVec ),
indexVec.size(),
toRawPtr( valVec ),
toRawPtr( segVec ),
toRawPtr( valVec2 ),
toRawPtr( segVec2 ) );
// Swap back into original vectors
valVec.swap( valVec2 );
segVec.swap( segVec2 );
这种手写排序需要 0.03 秒,并且这种性能在所有迭代中都是一致的,这与使用 sort_by_key 和 zip_iterator 看到的性能下降不同。
【问题讨论】:
这仍然是 Thrust 1.6 的问题吗? 【参考方案1】:为了在每个循环中准确计时,您需要在每个循环结束时使用 cudaThreadSynchronize。您获得的前两个循环的时间可能不是您正在寻找的实际时间。
【讨论】:
Pavan:我在记录时间之前使用的是 cudaThreadSynchronize,并且时间使用的是 Windows 高分辨率计时器 API。以上是关于推力:sort_by_key 与 zip_iterator 性能的主要内容,如果未能解决你的问题,请参考以下文章
推力::设备向量使用推力::替换或推力::转换与自定义函子/谓词
将 cv::cuda::GpuMat 与推力和测试推力 API 一起使用时出现问题
cuda 推力::for_each 与推力::counting_iterator