4

问题

我正在使用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 看到的性能下降不同。

4

1 回答 1

1

为了在每个循环中准确计时,您需要在每个循环结束时使用 cudaThreadSynchronize。您为前两个循环获得的时间可能不是您正在寻找的实际时间。

于 2011-04-22T19:03:21.530 回答