Задача
Я использую sort_by_key
, а значения передаются с помощью 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() ) ) );
Размер вектора обычно составляет около 4 миллионов. В начальные 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.