介绍
哈Ha!
按照我的标准,我已经写了很长时间的C ++代码,但是直到那时我还没有遇到与并行计算有关的任务。我还没有看过有关Boost.Compute库的文章,因此本文将对此进行介绍。
所有部分
- 第1部分
- 第2部分
内容
- 什么是boost.compute
- 将boost.compute连接到项目时出现问题
- boost.compute简介
- 基本计算类别
- 入门
- 结论
什么是boost.compute
这个c ++库提供了一个简单的高级接口,用于与多核CPU和GPU计算设备进行交互。此库最初是在1.61.0版中添加的,以增强功能,但仍受支持。
将boost.compute连接到项目时出现问题
因此,在使用该库时遇到了一些问题。其中之一是,如果没有OpenCL,该库就无法正常工作。编译器给出以下错误:
连接后,所有内容均应正确编译。
可以使用boost库下载它,并使用NuGet程序包管理器将其下载并连接到Visual Studio项目。
boost.compute简介
安装所有必需的组件之后,您可以查看简单的代码段。为了正确操作,以这种方式启用计算模块就足够了:
#include <boost/compute.hpp>
using namespace boost;
值得注意的是,常规stl容器不适合在计算名称空间算法中使用。而是有一些特殊创建的容器,它们与标准容器没有冲突。样例代码:
std::vector<float> std_vector(10);
compute::vector<float> compute_vector(std_vector.begin(), std_vector.end(), queue);
// , .
您可以使用copy()函数将其转换回std :: vector:
compute::copy(compute_vector.begin(), compute_vector.end(), std_vector.begin(), queue);
基本计算类别
该库包括三个辅助类,足以在视频卡和/或处理器上进行计算:
- 计算::设备(将确定我们将使用的设备)
- 计算::上下文(此类的对象存储OpenCL资源,包括内存缓冲区和其他对象)
- compute :: command_queue(提供用于与计算设备进行交互的接口)
您可以这样声明整个事情:
auto device = compute::system::default_device(); //
auto context = compute::context::context(device); //
auto queue = compute::command_queue(context, device); //
即使只使用上面的第一行代码,您也可以通过运行以下代码来确保一切正常运行:
std::cout << device.name() << std::endl;
因此,我们获得了将在其上进行计算的设备的名称。结果(您可能会有所不同):
入门
让我们来看一下trasform()和reduce()函数:
std::vector<float> host_vec = {1, 4, 9};
compute::vector<float> com_vec(host_vec.begin(), host_vec.end(), queue);
//
// copy()
compute::vector<float> buff_result(host_vec.size(), context);
transform(com_vec.begin(), com_vec.end(), buff_result.begin(), compute::sqrt<float>(), queue);
std::vector<float> transform_result(host_vec.size());
compute::copy(buff_result.begin(), buff_result.end(), transform_result.begin(), queue);
cout << "Transforming result: ";
for (size_t i = 0; i < transform_result.size(); i++)
{
cout << transform_result[i] << " ";
}
cout << endl;
float reduce_result;
compute::reduce(com_vec.begin(), com_vec.end(), &reduce_result, compute::plus<float>(),queue);
cout << "Reducing result: " << reduce_result << endl;
当您运行上述代码时,您应该看到以下结果:
我选择了这两种方法,因为它们很好地展示了并行计算的原始工作,而没有多余的东西。
因此,transform()函数用于通过将一个函数应用于所有值来更改数据数组(或两个数组,如果我们要传递它们的话)。
transform(com_vec.begin(),
com_vec.end(),
buff_result.begin(),
compute::sqrt<float>(),
queue);
让我们继续解析参数,前两个参数传递一个输入数据向量,第三个参数传递一个指向向量开始处的指针,将结果写入其中,下一个参数指示我们需要做的事情。在上面的示例中,我们使用标准矢量处理功能之一,即提取平方根。当然,您可以编写一个自定义函数,boost为我们提供了两种完整的方法,但这已经是下一部分的材料(如果有的话)。好吧,作为最后一个参数,我们传递了我上面提到的compute :: command_queue类的对象。
下一个函数是reduce(),这里的所有内容都更加有趣。此方法返回将第四个参数应用于向量的所有元素的结果。
compute::reduce(com_vec.begin(),
com_vec.end(),
&reduce_result,
compute::plus<float>(),
queue);
现在,我将通过一个示例进行说明,可以将上面的代码与以下等式进行比较:
在我们的例子中,我们得到了数组中所有元素的总和。
结论
好,仅此而已,我认为这足以对大数据进行简单的操作。现在,您可以使用boost.compute库的原始功能,并且还可以防止在使用该库时出现一些错误。
我很高兴收到积极的反馈。感谢您的时间。
祝你们好运!