Сравнить и поменять 2D массив

Я пытаюсь записать в 2d массив (float ** W) атомарно из разных потоков. Однако CAS всегда выдает эту ошибку: несовместимый тип для аргумента 1 __sync_bool_compare_and_swap

c = __sync_bool_compare_and_swap(&W[uu][i], a, b);

Он работает нормально, как обычно, когда я пишу атомарно в 1d массив.

Любые идеи о том, как сделать эту работу? Я могу попробовать создать 1d массивы в каждом потоке, а затем обновить этот 2d массив после барьера, но это заняло бы слишком много памяти. Я использую Ubuntu / Linux.

Благодарю.

1

Решение

main() {
int* W = malloc(10);
int uu = 1, i = 3;
__sync_val_compare_and_swap(&W[uu], 1, 2);
}

Компилируется нормально, однако:

main() {
float* W = malloc(10);
int uu = 1, i = 3;
__sync_val_compare_and_swap(&W[uu], 1.0f, 2.0f);
}

Не компилируется, давая мне точно такое же сообщение, которое вы написали. Что говорит о том, что поплавки не поддерживаются:

Определение, данное в документации Intel, допускает только
использование типов int, long, long long, а также их unsigned
двойники. GCC допускает любой интегральный скаляр или тип указателя, который
имеет длину 1, 2, 4 или 8 байт.

и, похоже, это подтверждает это.

Если вы не используете Itanium, то, возможно,

Четыре неарифметических функции (загрузка, сохранение, обмен и
compare_exchange) у всех также есть универсальная версия. Это родовое
Версия работает на любом типе данных.

вы могли бы использовать __atomic_compare_exchange* потому что они должны работать на любых типах в соответствии с документами. Я еще не пробовал это все же.

Редактировать:

main() {
float* W = malloc(10);
float target;
float val = 5.0f;
__atomic_exchange(&W[4], &val, &target, __ATOMIC_RELAXED);
}

^ — это как минимум компилируется.

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector