我正在设计并行算法,理论上,我想为每个线程更新std::list<...>
。所以说我有m*n
个线程,每个线程将索引一个特定的std::list
,在执行并行算法之后,所有列表将合并在一起。
我想到的其他方法是使用单个std::list
并在更新时锁定访问权限(如果在openCL中可能不完全确定)。
我的问题一般是......是否可以将stl数据结构传递给内核?
谢谢
答案 0 :(得分:1)
通常无法将标准库数据结构传递给OpenCL。存储在std::list
中的对象的内存布局不是连续的,因此您必须在传递给OpenCL之前将列表复制到缓冲区中。
std::vector
会更容易,因为至少它的内存是连续的,但你仍然需要转移到OpenCL缓冲区和从OpenCL缓冲区转移。
答案 1 :(得分:1)
OpenCL有{+ 3}}的C ++绑定。它在示例示例(inputA,inputB,output)中有2或3个使用场景。
我没有看到stl :: list的任何绑定,因为基础数据结构,我不希望这样。 std :: vector为它的data()
缓冲区提供了连续的内存分配,因此就内核而言,它只是一块内存。
STL向量data()
位置可以在添加元素时更改位置。如果预分配缓冲区中没有足够的空间,则重新分配具有更大大小的新缓冲区。如果您正在处理矢量并尝试向其添加元素,这将导致问题。这是你什么时候锁定&#34;在内核处理时阻止修改的向量(或使用CoR创建克隆)。
STL向量可以采用分配器,该示例包含一个SVMAllocator。这将允许您使用SVMUnMap(可能)将内存上传到服务器(CoR)。
关于如何构建程序......在接近多线程时,您可以从确定读/写角色开始。谁是生产者,谁是消费者?它是多生产者/单一消费者吗?单一生产者/多消费者?单一生产者/单一消费者?
你的内核如何工作?它们是只读输入还是只写输出?执行命令时,是上传到服务器的数据的副本吗?
您的生产者如何运作?他们是否知道他们需要的元素数量?你能用一个大的矢量并提供小块吗?
您熟悉Map / Reduce设计吗?写入时复制?副本上阅读?并发缓冲区?双缓冲?
关于线程的另一件事是他们不必总是必须运行。可以signal
一个线程开始工作,然后等待它完成(另一个"join"
信号)。在此帧期间,您可以使用双缓冲方法在一个线程中生成数据并在另一个线程中使用它(即上载命令)。在"join"
之后,您可以交换缓冲区。每个线程都在自己的缓冲帧上工作,你不需要锁。您的缓冲区看起来像{ [input, output]:Frame, [input, output]:Frame }
,您只需交换指针{ Frame*, Frame* }
。
有时您可以有效使用多少个线程也有一个上限。当然,多核CPU正在扩展,GPU有数百个线程,但除非你了解如何调度和中断线程,否则总是更好。以here is an example with std::vector之间的设计差异为例。
我希望这给你很多研究/思考。快乐的编码!