C++:Fast/parallel 计算两个“std::vector<double>”向量之间的 L1 距离
C++: Fast/parallel computation of L1 distance between two `std::vector<double>` vectors
我正在一台带有 Nvidia GPU 和 Cuda8 的机器上工作,我有一个 C++ 应用程序应该计算由 std::vector<double>
表示的两个向量之间的 L1 距离。
目前,我的代码根本不是并行的,只使用 CPU:
double compute_l1_distance(const std::vector<double> &v1, const std::vector<double> &v2) {
if (v1.size() != v2.size()) {
return -1;
}
double result = 0;
for (int i = 0 ; i < v1.size() i++) {
double val = v1[i] - v2[i];
if (val < 0) {
val = 0 - val;
}
result += val;
}
return result;
}
如何提高此计算的性能?如何使用 GPU?是否有推荐的库可以使用 GPU 或任何其他优化快速完成工作?
我建议您使用 cuda
和 thrust
来利用 GPU。就性能而言。是的,它会更快。
请查看thispost。描述的很清楚。
如果您必须多次调用 compute_l1_distance
,您可以使用 pthread
调用该方法,从而并行执行它。
使用 thrust 库,它看起来像:
double compute_l1_distance(const std::vector<double> &v1,
const std::vector<double> &v2) {
if (v1.size() != v2.size()) {
return -1;
}
thrust::device_vector<double> dv1 = v1;
thrust::device_vector<double> dv2 = v2;
auto begin = thrust::make_zip_iterator(thrust::make_tuple(
dv1.begin(), dv2.begin()));
auto end = thrust::make_zip_iterator(thrust::make_tuple(
dv1.end(), dv2.end() ));
const auto l1 = [](const thrust::tuple<double,double>& arg) {
return fabs(thrust::get<0>(arg) - thrust::get<1>(arg));
}
const auto add = [](double a, double b) { return a+b; }
return thrust::transform_reduce(first, last, l1, 0.0, add);
}
我正在一台带有 Nvidia GPU 和 Cuda8 的机器上工作,我有一个 C++ 应用程序应该计算由 std::vector<double>
表示的两个向量之间的 L1 距离。
目前,我的代码根本不是并行的,只使用 CPU:
double compute_l1_distance(const std::vector<double> &v1, const std::vector<double> &v2) {
if (v1.size() != v2.size()) {
return -1;
}
double result = 0;
for (int i = 0 ; i < v1.size() i++) {
double val = v1[i] - v2[i];
if (val < 0) {
val = 0 - val;
}
result += val;
}
return result;
}
如何提高此计算的性能?如何使用 GPU?是否有推荐的库可以使用 GPU 或任何其他优化快速完成工作?
我建议您使用 cuda
和 thrust
来利用 GPU。就性能而言。是的,它会更快。
请查看thispost。描述的很清楚。
如果您必须多次调用 compute_l1_distance
,您可以使用 pthread
调用该方法,从而并行执行它。
使用 thrust 库,它看起来像:
double compute_l1_distance(const std::vector<double> &v1,
const std::vector<double> &v2) {
if (v1.size() != v2.size()) {
return -1;
}
thrust::device_vector<double> dv1 = v1;
thrust::device_vector<double> dv2 = v2;
auto begin = thrust::make_zip_iterator(thrust::make_tuple(
dv1.begin(), dv2.begin()));
auto end = thrust::make_zip_iterator(thrust::make_tuple(
dv1.end(), dv2.end() ));
const auto l1 = [](const thrust::tuple<double,double>& arg) {
return fabs(thrust::get<0>(arg) - thrust::get<1>(arg));
}
const auto add = [](double a, double b) { return a+b; }
return thrust::transform_reduce(first, last, l1, 0.0, add);
}