Concurrency D并发写入缓冲区

Concurrency D并发写入缓冲区,concurrency,buffer,d,Concurrency,Buffer,D,假设您有一个大小为N的缓冲区,必须将其设置为确定值(例如设置为零或其他值)。缓冲区中的该值设置被划分为M个线程,每个线程处理缓冲区的N/M个元素 缓冲区不能是不可变的,因为我们更改了值。消息传递也不起作用,因为禁止传递ref或数组(=指针)类型。所以它必须通过共享?不,因为在我的例子中,缓冲区元素的类型是creal,因此算术不是原子的 最后,主程序必须等待所有线程完成。假设每个线程只写入数组的一个子集,并且数组中没有任何线程与另一个线程重叠,或者以任何方式相互依赖 如何以并发方式写入(或修改)缓

假设您有一个大小为N的缓冲区,必须将其设置为确定值(例如设置为零或其他值)。缓冲区中的该值设置被划分为M个线程,每个线程处理缓冲区的N/M个元素

缓冲区不能是不可变的,因为我们更改了值。消息传递也不起作用,因为禁止传递ref或数组(=指针)类型。所以它必须通过
共享
?不,因为在我的例子中,缓冲区元素的类型是
creal
,因此算术不是原子的

最后,主程序必须等待所有线程完成。假设每个线程只写入数组的一个子集,并且数组中没有任何线程与另一个线程重叠,或者以任何方式相互依赖

如何以并发方式写入(或修改)缓冲区

PS:有时我可以简单地将数组分成M个连续的部分,但有时我会逐列遍历数组(数组是1D的,但表示2D数据)。这使得线程使用的单个数组实际上在母数组中交错。啊


编辑:我发现类型
shared(creal)[
可以工作,因为现在元素是共享的,而不是数组本身。我打赌你可以并行交错阵列。但也有一些缺点:

shared
存储类非常严格,因此必须为分配提供关键字。这使得它很难被封装;由于调用者必须提供数组,因此它必须传递一个
共享的
数组,而不能只是一般地传递一个常规数组,让处理函数担心并行性。不,调用函数也必须考虑并行性,以便处理函数接收共享数组,而无需将数组重新分配到
共享的
空间

还有一个非常奇怪的bug,当我在某些位置动态分配
shared(creal)[
时,它只是挂起在分配位置。看起来很随意,找不到罪犯。。。 在测试示例中,这是可行的,但在我的项目中不是。。。这原来是DMD/OptLink中的一个bug


EDIT2:我从来没有提到过,但它是用于实现FFT(快速傅立叶定理)。因此,我无法选择精确的缓存对齐切片。我只知道元素是creal类型,元素的数量是2的幂(每行/每列)。

您可以使用该模块


但是如果你想重新发明它,你可以使用shared(只允许一个线程同时访问某个元素是线程安全的,如果你用合适的
join()
Task.*force()
更好)

你尝试的听起来更像是并行而不是并发。您可以查看std.parallelism:只是一个元注释:如果阵列上的读/写是一个可能的瓶颈,请尝试调整切片大小,使其与缓存线边界对齐。否则,线程将相互碰撞缓存,您可能会看到明显的性能下降。@gmfawcett:或者,更简单地说,只需将工作单元设置得足够大,使线程之间共享的缓存线只占所用缓存线总数的一小部分。您能传递一条包含数组切片的消息吗?脏类型转换可以让您在需要时破坏类型系统。事实证明,并行和并发std LIB都可以用于此问题。
T[] buff;
foreach(ref elem;parallel(buff))elem=0;