C++ volatile и перегрузка операторов для приложения CUDA

У меня есть класс A, который я перегружаю оператором =. Однако требуется, чтобы мне нужно было сделать что-то вроде этого:

volatile A x;
A y;
x = y;

который вызвал ошибку при компиляции

error: no operator "=" matches these operands
       operand types are: volatile A = A

Если я удалил volatile, он компилируется. Есть ли способ скомпилировать это без удаления "volatile" (и при этом сохранить поведение volatile)?


По сути, это программа CUDA, в которой «x» является общей памятью (все потоки могут получать доступ и изменять ее значение). Я хочу, чтобы он был «изменчивым», чтобы избежать оптимизации компилятора и повторно использовать значение вместо доступа к адресу памяти.

Подробнее о проблеме: в начале A - это просто примитивный тип, например целое число, volatile работало, как и ожидалось, и не вызывало никаких проблем, теперь я хочу, чтобы это был пользовательский класс (например, целое число 128 бит). Я не уверен, почему С++ жалуется в этом случае, но не с примитивным типом данных.

Заранее спасибо.


person w00d    schedule 13.09.2010    source источник


Ответы (4)


Предполагая, что квалификация volatile необходима, вам нужно будет добавить изменчивый оператор присваивания к A (A& A::operator=(const A&) volatile).

const_cast<A&>(x) = y заставит его скомпилироваться, но технически вызовет неопределенное поведение и, безусловно, удалит гарантии, которые дает volatile.

person Mike Seymour    schedule 13.09.2010
comment
Спасибо ! Он скомпилирован. но очень жаль :(, это дает мне такое же поведение без энергозависимости - person w00d; 13.09.2010
comment
@iKid: какого поведения вы ожидали от volatile? - person Mike Seymour; 13.09.2010
comment
Я добавил пояснение к моему вопросу - person w00d; 13.09.2010
comment
Кроме того, тщательно продумайте, как вы на самом деле реализуете эту функцию - volatile означает, что место назначения может быть записано кем-то другим, пока вы его пишете, поэтому убедитесь, что вы установили ограничения памяти или что-то еще. - person M.M; 03.02.2015

Комментарий «volatile не очень полезен в многопоточности C++» не имеет отношения к вопросу, который специфичен для CUDA. volatile требуется для варп-синхронного кодирования в CUDA.

person ArchaeaSoftware    schedule 16.04.2011

volatile не так часто используется в многопоточности C++ (см. объяснение Дэйва Бутенхофа на http://www.lambdacs.com/cpt/FAQ.html#Q56). Недостаточно гарантировать, что ваша программа сбрасывает данные, записанные из локального кэша ядра, до такой степени, что другие программы могут видеть обновления в общей памяти, и, учитывая, что в наши дни почти все многоядерные процессоры, это серьезная проблема. Я предлагаю вам использовать надлежащие методы синхронизации потоков, такие как boost, если ваша переносимость соответствует этому, или, возможно, мьютексы POSIX и условные переменные, в противном случае более зависимые от архитектуры методы, такие как барьеры памяти или атомарные операции, которые неявно синхронизируют память между ядрами.

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

person Tony Delroy    schedule 13.09.2010
comment
Особенно учитывая, что pthread_mutexes может быть невероятно легким. - person doron; 13.09.2010
comment
Потому что все работают на POSIX, амирите? - person Puppy; 13.09.2010
comment
@DeadMG: нет, поэтому у нас есть переносимые оболочки, такие как Boost.Thread, и библиотека поддержки потоков C++0x. - person Mike Seymour; 13.09.2010
comment
В яблочко. Напрямую рекомендовать POSIX просто неправильно по сравнению с boost::thread. - person Puppy; 13.09.2010
comment
Спасибо, ощущение, что C++ был плохо спроектирован в этом случае - person w00d; 13.09.2010
comment
volatile не так часто используется в C++. Это такая же чепуха, как и утверждение, что const не так уж часто используется в C++. Проблема с volatile заключается не в volatile, а в программистах, которые думают, что volatile — это какой-то волшебный примитив синхронизации потоков, который не работает. Это не. - person John Dibling; 13.09.2010
comment
@DeadMG/Mike: честное слово - ответ обновлен. @John: посмотрите ссылку, которую я вставил - она ​​не требуется для синхронизации между потоками и может снизить производительность. Может по-прежнему быть полезным для обработки асинхронного сигнала или низкоуровневого управления устройством и т. Д., Но это не имеет отношения к вопросу ... обновил мою формулировку в ответе, чтобы отразить это. - person Tony Delroy; 14.09.2010
comment
спасибо, ребята, больше всего расстроило то, что это работает в случае примитивного типа данных, но в классе объектов. Если нет возможности повторно использовать старый (который я хочу сохранить быстрым), я должен закодировать очень похожий метод только ради энергонезависимой адаптивности. - person w00d; 14.09.2010
comment
@iKid: не позволяй себе думать, что примитивные типы работают. Простая компиляция не является гарантией надежных результатов на многопроцессорном/ядерном компьютере. Даже если ваше тестирование на такой машине выглядит нормально, оно все равно может сломаться, когда вашей программе не повезет, и она будет вытеснена и помещена на другой ЦП... скорее всего, когда хост сильно загружен. Вы просто должны использовать надлежащие механизмы синхронизации, если вам нужна надежная программа... для этого они и предназначены. Если вы действительно измеряете производительность с помощью мьютекса и это проблема, вы можете попробовать атомарную операцию. - person Tony Delroy; 14.09.2010

Объявление конструктора копирования

volatile A& operator=(volatile A&) volatile;

работал у меня с nvcc. Обратите внимание, что вам, возможно, придется передать непримитивный тип только по ссылке. В противном случае вам понадобится больше конструкторов копирования, которые преобразуют изменчивые экземпляры в неизменяемые всякий раз, когда непримитивный тип передается по значению в неизменяемый параметр. Это действительно сводится к установлению volatile-корректности (во многом похожей на const-корректность).

person jascha    schedule 23.09.2011