@ tat0: bạn cũng có thể chơi xung quanh với Arrayfire: tìm kiếm vectorized sử dụng LOWER_BOUND() không cung cấp cho bạn câu trả lời ngay lập tức trong khi với setintersect() trong arrayfire, bạn sẽ có được "ngã tư" của hai mảng trực tiếp:
float A_host[] = {3,22,4,5,2,9,234,11,6,17,7,873,23,45,454};
int szA = sizeof(A_host)/sizeof(float);
float B_host[] = {345,5,55,6,7,8,19,2,63};
int szB = sizeof(B_host)/sizeof(float);
// initialize arrays from host data
array A(szA, 1, A_host);
array B(szB, 1, B_host);
array U = setintersect(A, B); // compute intersection of 2 arrays
int n_common = U.elements();
std::cout << "common: ";
print(U);
sự đầu ra là: phổ biến: U = 2,0000 5,0000 6,0000 7,0000
để có được những vị trí thực tế của các yếu tố trong mảng A, bạn có thể sử dụng xây dựng sau (với điều kiện các yếu tố A là duy nhất):
int n_common = U.elements();
array loc = zeros(n_common); // empty array
gfor(array i, n_common) // parallel for loop
loc(i) = sum((A == U(i))*seq(szA));
print(loc);
thì: loc = 4,0000 3,0000 8,0000 10,0000
Bên cạnh đó, lực đẩy :: LOWER_BOUND() có vẻ là chậm hơn so với setintersect(), i benchmarked nó với các chương trình sau đây:
int *g_data = 0;
int g_N = 0;
void thrust_test() {
thrust::device_ptr<int> A = thrust::device_pointer_cast((int *)g_data),
B = thrust::device_pointer_cast((int *)g_data + g_N);
thrust::device_vector<int> output(g_N);
thrust::lower_bound(A, A + g_N, B, B + g_N,
output.begin(),
thrust::less<int>());
std::cout << "thrust: " << output.size() << "\n";
}
void af_test()
{
array A(g_N, 1, g_data, afDevicePointer);
array B(g_N, 1, g_data + g_N, afDevicePointer);
array U = setintersect(A, B);
std::cout << "intersection sz: " << U.elements() << "\n";
}
int main()
{
g_N = 3e6; // 3M entries
thrust::host_vector<int> input(g_N*2);
for(int i = 0; i < g_N*2; i++) { // generate some input
if(i & 1)
input[i] = (i*i) % 1131;
else
input[i] = (i*i*i-1) % 1223 ;
}
thrust::device_vector<int> dev_input = input;
// sort the vector A
thrust::sort(dev_input.begin(), dev_input.begin() + g_N);
// sort the vector B
thrust::sort(dev_input.begin() + g_N, dev_input.begin() + g_N*2);
g_data = thrust::raw_pointer_cast(dev_input.data());
try {
info();
printf("thrust: %.5f seconds\n", timeit(thrust_test));
printf("af: %.5f seconds\n", timeit(af_test));
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
return 0;
}
và kết quả:
CUDA toolkit 4.2, tài xế 295,59
GPU0 GeForce GT 650m, 2048 MB, Tính toán 3.0 (đơn, đôi)
Memory Usage: 1937 MB (2048 MB tổng số)
lực đẩy: 0,13008 giây
arrayfire: 0,06702 giây