У меня есть класс А, который перегружает его оператор =. Однако требуется, чтобы мне нужно было сделать что-то вроде этого:
volatile A x;
A y;
x = y;
который вызвал ошибку при компиляции
error: no operator "=" matches these operands
operand types are: volatile A = A
Если я удалю volatile, он будет компилироваться. Есть ли способ скомпилировать этот файл без удаления "изменчивого" (и по-прежнему сохранять поведение волатильности)?
В основном это программа CUDA, в которой "x" является общей памятью (все потоки могут получить доступ и изменить ее значение). Я хочу, чтобы он был "изменчивым", чтобы избежать оптимизации компилятора и повторного использования значения вместо доступа к адресу памяти.
Подробнее о проблеме: в начале A является просто примитивным типом, например, integer, volatile работает как ожидалось и не вызывает никаких проблем, теперь я хочу, чтобы это был пользовательский класс (например, 128-битный). Я не уверен, почему С++ жалуется в этом случае, но не на примитивный тип данных.
Спасибо заранее.
Ответ 1
Предполагая, что квалификация volatile
необходима, вам нужно добавить оператор volatile присваивания к A (A& A::operator=(const A&) volatile
).
const_cast<A&>(x) = y
заставит его скомпилировать, но технически приведет к поведению undefined и, безусловно, удалит гарантии, предоставленные volatile
.
Ответ 2
volatile не очень полезен в потоке С++ (см. объяснение Dave Butenhof на http://www.lambdacs.com/cpt/FAQ.html#Q56). Этого недостаточно для обеспечения того, чтобы ваша программа сбрасывала данные, записанные из основного локального кеша, в точку, где другие программы могут видеть обновления в общей памяти и, учитывая почти каждый многоядерный в эти дни, представляют серьезную проблему. Я предлагаю вам использовать правильные методы синхронизации потоков, такие как повышение, если ваша мобильность должна соответствовать ему, или, возможно, мьютексы POSIX и переменные условия, при отсутствии таких более зависимых от архитектуры методов, как барьеры памяти или атомные операции, которые неявно синхронизируют память между ядрами.
Я уверен, что вы хотите, чтобы он был быстрым, но быстрый и нестабильный, как правило, не так полезен, как медленный и надежный, особенно если вы отправляете продукт, который нестабилен на вашем аппаратном обеспечении клиента.
Ответ 3
"volatile не очень много используется в потоке С++" комментарий не имеет отношения к вопросу, который является специфичным для CUDA. летучесть необходима для синхронного кодирования warp в CUDA.
Ответ 4
Объявление конструктора копирования
volatile A& operator=(volatile A&) volatile;
работал у меня с nvcc. Обратите внимание, что вам может потребоваться передать только не примитивный тип только по ссылке. Кроме того, вам понадобится больше конструкторов-копий, которые преобразуют volatile-экземпляры в энергонезависимые, когда не-примитивный тип передается по значению в энергонезависимый параметр.
Это действительно сводится к установлению изменчивости-правильности (как и const-correctness).