powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Нужно писать volatile для ссылочных полей?
9 сообщений из 9, страница 1 из 1
Нужно писать volatile для ссылочных полей?
    #39449195
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Например имеем
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public class Test {
	volatile Dictionary<UInt64, Int32> list = new Dictionary<UInt64, Int32>();

	public void Fill() {
		var tmp = new Dictionary<UInt64, Int32>();
		... заполнение
		list = tmp;
	}

	public Int32 Get(UInt64 v) {
		Int32 ret = -1;
		list.TryGetValue(v, out ret);
		return ret;
	}
}



Т.е. Dictionary периодически заполняется (кэш справочника из БД) и сохраняется в list, далее никаких изменений Dictionary, только чтение.
Fill() и Get() вызываются из разных потоков.

Может прога аварийно завершиться если не указать volatile ?

Мне кажется что нет, но есть сомнения. Как понимаю реально list это ссылка на объект (переменная с адресом объекта), которая перезаписывается при list = tmp. Как понимаю присвоение это одна команда асма, т.е. все атомарно произойдет независимо от volatile, а volatile просто запрещает какое-либо кэширование ссылки оптимизатору.
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449225
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак понимаю присвоение это одна команда асма, т.е. все атомарно произойдет независимо от volatileЭто да.
Dima Tа volatile просто запрещает какое-либо кэширование ссылки оптимизатору.Запрещает кэширование значения переменной в кэше CPU.

Если не поставить volatile, то при наличии нескольких CPU, каждый со своим кэшем, второй поток может работать с предыдущим объектом Dictionary несмотря на то, что первый поток записал в переменную list новое значение.
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449229
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volatile не нужен
Код подозрительный, но если ты гарантируешь, что Fill() два раза одновременно не вызывается, и что Get() вызовется после того, как отработает Fil(), то и ладно. Но все же синхронизацию я бы впилил
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449232
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
1. volatile тебе тут не надо.
2. открой для себя Класс ConcurrentDictionary<TKey, TValue>
3. открой для себя Класс Lazy<T>
4. тебе в данном случае больше подойдет lock и аналоги, хотя последние лучше применять съев на том собаку
5. такое кеширование иногда может быть медленнее чтения каждый раз из БД, сравни производительность 2 вариантов
6. для общего развития почитай по теме memoization, можно раз и навсегда написав несколько методов кешировать легким движением руки все, что угодно (я так и делаю : ))
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449286
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КЕсли не поставить volatile, то при наличии нескольких CPU, каждый со своим кэшем, второй поток может работать с предыдущим объектом Dictionary несмотря на то, что первый поток записал в переменную list новое значение.
Собственно поэтому и не хочу писать. Тут замеры проводил .
PallarisКод подозрительный, но если ты гарантируешь, что Fill() два раза одновременно не вызывается
Fill() потокобезопасный. Заполняется локальный Dictionary.
ЕвгенийВ2. открой для себя Класс ConcurrentDictionary<TKey, TValue>
3. открой для себя Класс Lazy<T>
4. тебе в данном случае больше подойдет lock и аналоги, хотя последние лучше применять съев на том собаку
5. такое кеширование иногда может быть медленнее чтения каждый раз из БД, сравни производительность 2 вариантов
6. для общего развития почитай по теме memoization, можно раз и навсегда написав несколько методов кешировать легким движением руки все, что угодно (я так и делаю : ))
ConcurrentDictionary в разы тормознее. Да и не нужен он. Как и прочие блокировки. Нужен Dictionary в режиме readonly.
Прога автономно работать будет. БД далеко в инете, связь может пропадать и т.д. и т.п. Достаточно обновления раз в час.
Почитал про memoization , это по сути оно и есть, только не записями, а сразу таблицей.
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449317
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Зная тебя как фанатичного маньяка перфоманса, могу еще порекомендовать следующее.
Если, как в твоем случае, нужен ридонли словарь, можно прибегнуть к динамическим кодогенерации и компиляции.
Например твой словарь можно описать примерно так.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  static Int32 Test(UInt64 stc)
        {
            switch (stc)
            {
                case 4512: return 78;
                case 895: return 89;
                case 8954: return 32;
                case 3652: return 98;
                default: return 0;
            }
        }



Компилятор C# же, трансформирует это в
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
private static int Test(ulong stc)
{
	int result;
	if (stc <= 3652uL)
	{
		if (stc == 895uL)
		{
			result = 89;
			return result;
		}
		if (stc == 3652uL)
		{
			result = 98;
			return result;
		}
	}
	else
	{
		if (stc == 4512uL)
		{
			result = 78;
			return result;
		}
		if (stc == 8954uL)
		{
			result = 32;
			return result;
		}
	}
	result = 0;
	return result;
}


То есть никаких тебе хешфункций и прочей внутренней кухни Dictionary<UInt64, Int32>, минимум действий для получения результата. Си с плюсами, со всеми его STL и Boost нервненько курит в сторонке.
P. S. как создать и подгрузить динамическую сборку разберешся?
P. P. S. давно хочу замутить такой словарик, да все лень.
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449362
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВDima T,
Зная тебя как фанатичного маньяка перфоманса, могу еще порекомендовать следующее.
Если, как в твоем случае, нужен ридонли словарь, можно прибегнуть к динамическим кодогенерации и компиляции.
В моем случае это не подойдет, т.к. записей под миллион, т.е. исходник на 1 млн. строк ... я не на столько маньяк :)

Можно сделать массив структур {UInt64 key, Int32 value}, отсортировать по key и искать Array.BinarySearch() ИМХО тоже самое что твой switch(). Потом затестю. Так еще память экономится.

switch() был бы быстрее массива, если бы key имели близкие значения, т.к. при этом дерево if`ов заменяется таблицей переходов 17655427 , правда это в С/С++, но в C# возможно также. Но это не мой случай, т.к. key это хэш.
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449475
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Dima T]ЕвгенийВВ моем случае это не подойдет, т.к. записей под миллион, т.е. исходник на 1 млн. строк ... я не на столько маньяк :)

Думаешь компилятор не справиться? :)
...
Рейтинг: 0 / 0
Нужно писать volatile для ссылочных полей?
    #39449488
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВДумаешь компилятор не справиться? :)
Справится наверно, но раз в час генерить такой исходник, компилировать, гонять по инету, компиляция IL-кода при первом обращении... Изврат какой-то.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Нужно писать volatile для ссылочных полей?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]