问题
我正在使用sort_by_key
使用 a 传递的值zip_iterator
。这sort_by_key
被调用了很多次,并且在一定的迭代之后它变得慢了 10 倍!这种性能下降的原因是什么?
症状
我正在使用 对 3 个向量进行排序sort_by_key
,其中一个作为关键向量:
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 看到的性能下降不同。