D одновременная запись в буфер - PullRequest
3 голосов
/ 30 ноября 2011

Скажем, у вас есть буфер размером N, который должен быть установлен на определенные значения (скажем, на ноль или что-то еще). Эта настройка значения в буфере делится на M потоков, каждый из которых обрабатывает N / M элементов буфера.

Буфер не может быть immutable, так как мы меняем значения. Передача сообщений также не будет работать, так как запрещено передавать типы ref или array (= pointer). Так должно произойти через shared? Нет, поскольку в моем случае элементы буфера имеют тип creal и, следовательно, арифметика не является атомарной.

В конце основная программа должна дождаться завершения всех потоков. Дано, что каждый поток записывает только в подмножество массива, и ни один из потоков не перекрывается в массиве с другим потоком или каким-либо образом зависит от другого.

Как бы я начал записывать (или модифицировать) буфер одновременно?

PS: иногда я могу просто разделить массив на М последовательных частей, но иногда я перебираю массив (массив 1D, но представляет 2D данные) столбец за столбцом. Что делает отдельные массивы, которые используются потоками, фактически чередующимися в материнском массиве. Argh.


РЕДАКТИРОВАТЬ: я понял, что тип shared(creal)[] будет работать, так как теперь элементы являются общими, а не сам массив. Бьюсь об заклад, вы могли бы распараллелить чередующиеся массивы. Однако есть и недостаток:

Класс хранения shared настолько строг, что выделение должно быть снабжено ключевым словом. Что делает его едва инкапсулированным; так как вызывающая сторона должна предоставить массив, она обязана передать массив shared и не может просто передать обычный массив и позволить функции обработки беспокоиться о параллелизме. Нет, вызывающая функция должна также беспокоиться о параллелизме, поэтому обрабатывающая функция получает общий массив и не нуждается в перераспределении массива в shared пространстве.

Существует также очень странная ошибка: когда я динамически выделяю shared(creal)[] в определенных местах, он просто зависает при выделении. Кажется очень случайным и не может найти виновника ... В тестовом примере это работает, но не в моем проекте ... Это оказалось ошибкой в ​​DMD / OptLink.


EDIT2: я никогда не упоминал, но это для реализации БПФ (теорема о быстром Фурье). Поэтому я не имею права выбирать точные фрагменты, выровненные по кешу. Все, что я знаю, это элементы типа creal, а количество элементов - степень 2 (на строку / столбец).

1 Ответ

2 голосов
/ 30 ноября 2011

вы можете использовать модуль std.parallelism

T[] buff;
foreach(ref elem;parallel(buff))elem=0;

, но если вы хотите заново изобрести это, вы можете просто использовать общий доступ (безопасно для потока только 1 поток доступа копределенный элемент в то время, и если вы обеспечите это с соответствующим join() или Task.*force(), тем лучше)

...