Я заинтересован в портировании некоторого существующего кода для использования тяги, чтобы посмотреть, смогу ли я относительно легко ускорить его на графическом процессоре.
Я хочу выполнить операцию сжатия потока, при которой будут храниться только ненулевые элементы. У меня это в основном работает, согласно приведенному ниже примеру кода. Часть, которую я не знаю, как решить, связана со всем дополнительным пространством заполнения, которое находится в d_res и, следовательно, в h_res после того, как произойдет уплотнение.
В примере просто используется последовательность 0-99 со всеми четными элементами, установленными на ноль. Это всего лишь пример, и настоящей проблемой будет общий разреженный массив.
Этот ответ здесь очень помог мне, хотя, когда дело доходит до считывания данных, размер просто известен как постоянный: Как быстро сжать разреженный массив с помощью 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;
}
Кроме того, я новичок в работе с тягой, поэтому, если приведенный выше код имеет какие-либо очевидные недостатки, противоречащие рекомендуемым практикам использования тяги, сообщите мне об этом.
Точно так же скорость всегда представляет интерес. Читая некоторые из различных руководств по тяге, кажется, что здесь небольшие изменения, и могут быть большие сбережения скорости или потери. Поэтому, пожалуйста, дайте мне знать, если есть умный способ ускорить это.