Я заинтересован в переносе существующего кода на использование тяги, чтобы узнать, могу ли я ускорить его на GPU с относительной легкостью.Сжатие потока с помощью тяги; лучшие практики и быстрый способ?
То, что я хочу выполнить, - операция уплотнения потока, в которой будут храниться только ненулевые элементы. У меня это в основном работает, например, в примере кода. Часть, в которой я не уверен, как бороться, имеет дело со всем дополнительным заполняющим пространством, которое находится в d_res и, таким образом, h_res, после того, как произойдет уплотнение.
В примере просто используется последовательность 0-99 со всеми четными элементами, установленными на ноль. Это всего лишь пример, и реальной проблемой будет общий разреженный массив.
Этот ответ здесь мне очень помог, хотя, когда дело доходит до считывания данных, размер как раз известно, что константа: How to quickly compact a sparse array with CUDA C?
Я подозреваю, что я могу работать вокруг этого путем подсчета числа 0-х в d_src, а затем выделяет только d_res для этого размера или делает счет после уплотнения и копирует только этот элемент. Это действительно правильный способ сделать это?
У меня есть смысл, что для этого будет какое-то легкое исправление, благодаря умному использованию итераторов или некоторой другой особенности тяги.
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/copy.h>
//Predicate functor
struct is_not_zero
{
__host__ __device__
bool operator()(const int x)
{
return (x != 0);
}
};
using namespace std;
int main(void)
{
size_t N = 100;
//Host Vector
thrust::host_vector<int> h_src(N);
//Fill with some zero and some nonzero data, as an example
for (int i = 0; i < N; i++){
if (i % 2 == 0){
h_src[i] = 0;
}
else{
h_src[i] = i;
}
}
//Print out source data
cout << "Source:" << endl;
for (int i = 0; i < N; i++){
cout << h_src[i] << " ";
}
cout << endl;
//copies to device
thrust::device_vector<int> d_src = h_src;
//Result vector
thrust::device_vector<int> d_res(d_src.size());
//Copy non-zero elements from d_src to d_res
thrust::copy_if(d_src.begin(), d_src.end(), d_res.begin(), is_not_zero());
//Copy back to host
thrust::host_vector<int> h_res(d_res.begin(), d_res.end());
//thrust::host_vector<int> h_res = d_res; //Or just this?
//Show results
cout << "h_res size is " << h_res.size() << endl;
cout << "Result after remove:" << endl;
for (int i = 0; i < h_res.size(); i++){
cout << h_res[i] << " ";
}
cout << endl;
return 0;
}
Кроме того, я новичок с тягой, так что, если приведенный выше код имеет какие-либо очевидные недостатки, которые идут против рекомендуемой практики использования тяги, пожалуйста, дайте мне знать.
Аналогично, скорость всегда представляет интерес. Читая некоторые из различных руководств по упорству, здесь, кажется, небольшие изменения, и там могут быть большие сберегатели скорости или расточители. Поэтому, пожалуйста, дайте мне знать, если есть умный способ ускорить это.
Это именно то, что я искал, спасибо. Похоже, что «remove» имеет аналогичный возврат, поэтому теперь я также могу сравнить время этого подхода remove-then-sort на reverse, sort-then-remove. –