2010-09-13 2 views
10

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

volatile A x; 
A y; 
x = y; 

который поднял ошибку при компиляции

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

Если я удалил изменчив, это компилируется. Нужно ли это скомпилировать, не удаляя «изменчивый» (и все еще сохраняя поведение волатильности)?


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

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

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

ответ

7

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

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

+0

Спасибо! Он скомпилирован. но слишком плохо :(, это дает мне такое же поведение нестабильности – w00d

+0

@iKid: какое поведение вы ожидали от 'volatile'? –

+0

Я добавил объяснение на мой вопрос – w00d

2

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

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

+0

Особенно учитывая, что 'pthread_mutex's может быть невероятно легким – doron

+0

Потому что все работают на POSIX, амирите? – Puppy

+0

@DeadMG: нет, поэтому у нас есть переносные обертки, такие как Boost.Thread и библиотека поддержки потоков на C++ 0x. –

2

Замечание «volatile is not much use in C++ threading» не имеет отношения к вопросу, который является специфичным для CUDA. летучесть необходима для синхронного кодирования warp в CUDA.

1

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

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

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