将 stl 数据结构传递给 opencl 内核

Passing stl data structure to an opencl kernel

本文关键字:opencl 内核 stl 数据结构      更新时间:2023-10-16

我正在设计一种并行算法,理论上,我想更新每个线程的std::list<...>。假设我有m*n线程,每个线程都会索引一个特定的std::list,在并行算法执行后,所有列表都将合并在一起。

我想到的另一种方法是使用单个std::list并在更新时锁定访问权限(如果在 openCL 中可能的话,不完全确定(。

我的问题通常是...是否可以将 STL 数据结构传递给内核?

谢谢

一般不可能将标准库数据结构传递给 OpenCL。存储在std::list中的对象的内存布局不是连续的,因此您必须在传递给 OpenCL 之前将列表复制到缓冲区中。

std::vector会更容易,因为至少它的内存是连续的,但您仍然需要与 OpenCL 缓冲区之间传输。

OpenCL 有C++绑定,下面是一个 std::vector 的示例。 它在示例示例中有 2 或 3 个使用场景(输入 A、输入 B、输出(。

我没有看到 stl::list 的任何绑定,由于底层数据结构,我不希望看到。 std::vector 有一个连续的内存分配,因为它data()缓冲区,所以就内核而言,它只是一块内存。

添加元素时,STL 向量data()位置可以更改位置。 如果预分配的缓冲区中没有足够的空间,则会重新分配更大大小的新缓冲区。 如果您正在处理向量并尝试向其添加元素,这将导致问题。 这是您在内核处理时"锁定"向量以防止修改(或使用 CoR 创建克隆(的时候。

STL 向量可以采用分配器,该示例包含一个 SVMA 定位器。 这将允许您使用 SVMUnMap 将内存(大概(上传到服务器 (CoR(。


至于如何构建你的程序...在处理多线程时,可以从确定读/写角色开始。 谁是生产者,谁是消费者? 是多生产者/单一消费者吗?单一生产者/多消费者? 单一生产者/单一消费者?

你的内核是如何工作的? 它们在输入上是只读的,在输出上是只写的吗?执行命令时,数据的副本是否上传到服务器?

您的生产商如何运作? 他们是否提前知道他们需要的元素数量? 你能只使用一个大向量并配置小块吗?

你熟悉地图/化简设计吗?写入时复制?读取时复制? 并发缓冲区?双重缓冲?

关于线程的另一件事是它们不必总是运行。可以signal线程开始工作,然后等待它完成(另一个"join"信号(。 在此帧期间,您可以使用双缓冲方法在一个线程中生成数据并在另一个线程中使用它(即上传命令(。"join"后,您可以交换缓冲区。 由于每个线程都在自己的缓冲帧上工作,因此不需要锁。 您的缓冲区看起来像{ [input, output]:Frame, [input, output]:Frame },您只需将指针交换{ Frame*, Frame* }

有时,您可以有效使用的线程数也有上限。 当然,多核CPU正在扩展,GPU有数百个"线程",但除非你了解线程是如何调度和中断的,否则更多并不总是更好的。 以 Node.JS 和 Apache 之间的设计差异为例。

我希望这能给你很多研究/思考。 祝您编码愉快!