powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Максимальный размер ConcurrentDictionary в 32-битных приложениях
196 сообщений из 196, показаны все 8 страниц
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244003
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делаю так:

Код: c#
1.
2.
3.
4.
5.
6.
public static ConcurrentDictionary<int, bool> Tested;

Tested = new ConcurrentDictionary<int, bool>(_threadsQty, mmax - mmin + 1);

for (int i = mmin; i <= mmax; i++) // добавляем записи с начальным значением false
    Tested.TryAdd(i, false);



Пока количество элементов = 2^24, всё работает. При 2^25 ловлю System.OutOfMemoryException.

Если же звать конструктор без параметров
Tested = new ConcurrentDictionary<int, bool>();

то Exception не ловится, а просто приложение "stop working".

В обоих случаях всё происходит в момент выделения процессу памяти ~1400000 кб.

Вопрос.
Есть ли ограничения на максимальное кол-во записей в ConcurrentDictionary, либо на размер выделенной под него памяти?
Либо имеет значение только общий размер памяти, выделенной 32-битному процессу?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244018
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшое уточнение: Exception ловится в момент заполнения словаря, после работы конструктора.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244022
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это проблема 32-битного процесса. Всего 4 Гб из них 2 Гб ОС, вторые 2 Гб проге, в них и .Net и твои данные.

В твоем случае лучше BitArray взять. Тут будет 1 бит - одно значение, т.е. все положительные значения Int32 (до 2^31) займут 256 Мб (2^28)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244036
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы взял BitArray, но он не потокобезопасен. В моём случае без вариантов подходит только что-то из System.Collections.Concurrent

Самое забавное в моей истории, что на 32-битной Windows 7 с 4 Гб ОЗУ иногда эта программа проходит описанную инициализацию и начинает работать, а на 64-битной Windows Server c большим количеством памяти устойчиво падает вышеописанным образом.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244051
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Я бы взял BitArray, но он не потокобезопасен.
Используй блокировки lock() . Быстрее будет чем с ConcurrentDictionary
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244057
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если еще быстрее надо, то взять массив Int32[], прописать логику работы с битами, а для чтения/записи использовать Interlocked функции.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244103
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока в порядке эксперимента переписал всё под BitArray, работает правильно как с ConcurrentDictionary без принятия специальных мер по блокировке. Что очень интересно, если вспомнить что с обычным массивом (в самой первоначальной версии программы) были чудеса.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244107
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®работает правильно как с ConcurrentDictionary без принятия специальных мер по блокировке.
Это твое "правильно" те еще грабли. Когда проблемы возникнут - исключений не будет, просто получишь неправильный результат своего расчета.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244121
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

ну, если задача чисто заполнить справочник и он уверен в том, что пересечений из разных потоков не будет, то по сути всё отработает без ошибок. Но это же бессмысленный пример в вакууме :) одним заполнением то, он не ограничится (наверное)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244146
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.к. работа с битами происходит через байты, то вполне возможна такая ситуация когда два потока одномоментно захотят установить разные биты в одном байте.
Например это может произойти так
Поток 1Поток 2Прочитал байтПрочитал байтУстановил бит 3Установил бит 5Записал байтЗаписал байт
в итоге то что сделал Поток 1 будет затерто, т.е. бит 3 не будет установлен.
Поэтому блокировки доступа при записи обязательны. При чтении можно не блокировать доступ, но тогда перед записью, внутри блокировки делать повторное чтение.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244148
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЭто твое "правильно" те еще грабли.

Всецело догадываюсь об этом и обещаю заблаговременно принять меры :)
А пока факт остаётся фактом: BitArray работает правильно там, где bool[] вынудил прибегнуть к ConcurrentDictionary, при числе потоков от 4 до 32.

Прироста скорости по сравнению с ConcurrentDictionary пока не обнаружил.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244164
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®bool[] вынудил прибегнуть к ConcurrentDictionary, при числе потоков от 4 до 32.
bool[] ничем не отличается от BitArray, разве что в 8 раз больше места требуется.
AR®Прироста скорости по сравнению с ConcurrentDictionary пока не обнаружил.
Можно не заметить если на работу с массивом уходит незначительная часть времени работы проги. Например если это 1%, то даже если в 10 раз ускорилось, то ускорение всего 0,9% от общего времени.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244196
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tbool[] ничем не отличается от BitArray, разве что в 8 раз больше места требуется.
Был бы готов согласиться, но эксперимент выявил обратное.

Dima TМожно не заметить если на работу с массивом уходит незначительная часть времени работы
Вполне допускаю. Примерно так оно в этой программе и есть.

Огорчает другое: при 2^25 элементов процесс запустился, а при 2^26 - уже нет.
Буду думать...
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244203
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже, теперь дохнет уже на выделении памяти объектам в каждом потоке.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244257
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T

Благодарю за "наводку" на класс BitArray.

Скажите, будет ли в общем случае достаточно брать в lock(){ } операции записи в массив?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244285
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Скажите, будет ли в общем случае достаточно брать в lock(){ } операции записи в массив?
Думаю да, но на 100% не уверен.

Лучше все обращения обернуть. Сделай класс-обертку, два метода Read() и Write(). В них пропиши c lock(). Как понял на общем времени работы твоего кода это особо не скажется, но надежность будет гарантированная.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244487
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По крайней мере размер требуемой памяти в этом случае оцинеть не сложно, так что рекомендую использовать MemoryFailPoint и ловить InsufficientMemoryException.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244514
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Скажите, будет ли в общем случае достаточно брать в lock(){ } операции записи в массив?
Посмотрел исходник bitarray.cs
Чтение
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
        public bool Get(int index) {
            if (index < 0 || index >= Length) {
                throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
            }
            Contract.EndContractBlock();
    
            return (m_array[index / 32] & (1 << (index % 32))) != 0;
        }


Думаю без lock() можно читать. Нечему тут глючить при многопоточности.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244811
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предварительный диагноз такой: с BitArray немного быстрее, чем с ConcurrentDictionary, но только пока не использую lock(){}.
С lock остаётся только преимущество в памяти (что для моего случая важно). Видимо потому, что блокировка накладывается на весь массив, а не на отдельный бит :)

Интересно, а можно ли скомпилировать 64-битное приложение на 32-битном компе?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244834
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®С lock остаётся только преимущество в памяти (что для моего случая важно). Видимо потому, что блокировка накладывается на весь массив, а не на отдельный бит :)
Блокировка вообще не накладывается. Это просто флаг, первый поток установил и что-то делает, второй, при попытке его установить - останавливается и ждет пока первый не снимет.

Можешь разделить массив на условные блоки (0-1048575, 1048576-... и т.д.) и использовать отдельный объект для блокировки каждого блока. Только учти что блоки массива, за который отвечает одна блокировка, должны быть кратны 32. Т.к. внутри BitArray используется Int32[].

AR®Интересно, а можно ли скомпилировать 64-битное приложение на 32-битном компе?
Скомпилировать можно, но оно не запустится.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244873
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TСкомпилировать можно, но оно не запустится.
Не запустится на компьютере компиляции - это устраивает.
Хотелось бы, чтобы оно запустилось на 64-битной ОС, где памяти стоит побольше, и не будет ограничения как для 32-битного процесса.
Никогда не делал так, потому спрашиваю.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244930
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®С lock остаётся только преимущество в памяти (что для моего случая важно). Видимо потому, что блокировка накладывается на весь массив, а не на отдельный бит :)
Можно Interlocked.CompareExchange() вместо lock(). Так вообще без блокировок. Только класс придется свой делать.
class ConcurrentBitArrayСкопипастил из BitArray только минимально нужное.
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
		public sealed class ConcurrentBitArray {
			Int32[] m_array;

			public ConcurrentBitArray(int length) {
				m_array = new Int32[(length - 1) / 32 + 1];
			}

			public bool this[int index] {
				get {return Get(index); }
				set {Set(index,value); }
			}

			public bool Get(int index) {
				return (m_array[index / 32] & (1 << (index % 32))) != 0;
			}

			public void Set(int index, bool value) {
				Int32 cur, val;
				do {
					cur = m_array[index / 32];
					if (value) {
						val = cur | (1 << (index % 32));
					} else {
						val = cur & ~(1 << (index % 32));
					}
				} while (cur != Interlocked.CompareExchange(ref m_array[index / 32], val, cur));
			}
		}


		static void Main(string[] args) {
			var b = new ConcurrentBitArray(1000);
			Console.WriteLine(b[100]);
			b[100] = true;
			Console.WriteLine(b[100]);
			b[200] = true;
			Console.WriteLine(b[200]);
			b[200] = false;
			Console.WriteLine(b[200]);
			return;
		}


AR®Хотелось бы, чтобы оно запустилось на 64-битной ОС, где памяти стоит побольше, и не будет ограничения как для 32-битного процесса.
Если по-простому: Внутри EXE находится IL-код, по месту запуска он может заработать и как х32 и как x64 без перекомпиляций. Можно явно задать чтобы везде одинаково было. Это в заголовке EXE указывается. Подробно у Рихтера расписано.
Как в студии настроить не знаю, а с командной строки так компилировать
Код: c#
1.
%windir%\Microsoft.NET\Framework\v4.0.30319\csc /o /out:MyProg.exe  program.cs


без указания платформы, тогда на x32 компе запустится как x32, на x64 как x64

Только не надейся что при x64 у тебя не выскочит OutOfMemory. Там тоже ограничения есть, виндовс как-то ограничивает чтобы приложение всю память не отъело.
И еще такой момент: x64 работает на ~30% медленнее чем х32.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244949
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за класс.
Dima TТолько не надейся что при x64 у тебя не выскочит OutOfMemory. Там тоже ограничения есть, виндовс как-то ограничивает чтобы приложение всю память не отъело.


Очень интересно, каковы они и где установливаются. Работает же как-то, ну например, SQL Server, который берёт, сколько ему нужно.


Dima TИ еще такой момент: x64 работает на ~30% медленнее чем х32.

Это с лихвой компенсировалось бы отсутствием ограничений на выделяемую процессу память. В процессе экспериментов я попутно выяснил, что, например, BitArray даёт время работы раза ~в 4 больше, чем bool[ ] (он используется у меня в каждом отдельном потоке).

И вот ещё интересный вопрос. Если делать свой класс, как ваш ConcurrentBitArray, с точки зрения минимизации времени работы, что лучше взять за основу: Int32, или более короткие Int16, byte, или наоборот, длинный Int64 ?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39244984
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Спасибо за класс.
Dima TТолько не надейся что при x64 у тебя не выскочит OutOfMemory. Там тоже ограничения есть, виндовс как-то ограничивает чтобы приложение всю память не отъело.


Очень интересно, каковы они и где установливаются. Работает же как-то, ну например, SQL Server, который берёт, сколько ему нужно.
Специально не интересовался, случайно нигде не попадалось, так что гугл в помощь если интересно. Наверно есть какое-нибудь WinAPI чтобы попросить ОС дать больше чем по умолчанию.
AR®Dima TИ еще такой момент: x64 работает на ~30% медленнее чем х32.
Это с лихвой компенсировалось бы отсутствием ограничений на выделяемую процессу память. В процессе экспериментов я попутно выяснил, что, например, BitArray даёт время работы раза ~в 4 больше, чем bool[ ] (он используется у меня в каждом отдельном потоке).
bool[ ] быстрее, т.к. там просто получение байта из массива (m_array[index]), без всяких доп.расчетов (m_array[index / 32] & (1 << (index % 32)))
AR®И вот ещё интересный вопрос. Если делать свой класс, как ваш ConcurrentBitArray, с точки зрения минимизации времени работы, что лучше взять за основу: Int32, или более короткие Int16, byte, или наоборот, длинный Int64 ?
Int16 и byte отпадают Interlocked.CompareExchange() перегружен только для Int32 и Int64. Работа с Int64 под x32 медленнее. В принципе можешь затестить как оно будет в твоей задаче.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39245021
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TInt16 и byte отпадают Interlocked.CompareExchange() перегружен только для Int32 и Int64

Я имел ввиду, что если городить совсем свой огород и не закладываться на использование Interlocked, в каком случае обращение к требуемому биту будет быстрее: с byte, Int16, Int32, Int64?
И ещё: byte и Int16 будут занимать в памяти в случае большого массива из них действительно байт и 2 соответственно?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39245051
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Dima TInt16 и byte отпадают Interlocked.CompareExchange() перегружен только для Int32 и Int64
Я имел ввиду, что если городить совсем свой огород и не закладываться на использование Interlocked, в каком случае обращение к требуемому биту будет быстрее: с byte, Int16, Int32, Int64?
Не знаю. Затести. Есть подозрение что будет одинаково по скорости (за исключением Int64 в х32 режиме). У процов есть свои тонкости, кое-какая заточка на 32-бита (выравнивание в памяти и т.д.).
Код легко меняется под нужный тип. Например если данные в byte[] то просто во всем коде замени 32 на 8, т.е. на количество бит в одном элементе массива.
AR®И ещё: byte и Int16 будут занимать в памяти в случае большого массива из них действительно байт и 2 соответственно?
Все верно. byte - 1 байт, Int16 - 2 байта.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39245084
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®выяснил, что, например, BitArray даёт время работы раза ~в 4 больше, чем bool[ ] (он используется у меня в каждом отдельном потоке).
Можно немного пооптимизировать. Заменить
Код: c#
1.
1 << (index % 32)


на массив
Код: c#
1.
static Int32[32] mask = new Int32[32];


заполнить его один раз и использовать
Код: c#
1.
mask[index % 32]


В С/С++ это дает ускорение, в C# не знаю, т.к. будет еще доп.проверка на выход за границу массива. Тоже мерить надо.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39247454
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вести с полей.
Таблица ниже содержит времена работы одного и того же алгоритма (чч:мм:сс.мс), в котором для массивов значений bool поочерёдно использовались разные технологии. Первая колонка - размер массивов в виде показателя степени двойки.

2^...bool[]BitArrayBoolArray8BoolArray16BoolArray32BoolArray641400:00:00.30000:00:00.46200:00:00.37200:00:00.36200:00:00.26200:00:00.4521500:00:00.63200:00:01.31200:00:00.82200:00:01.13200:00:00.89200:00:01.3721600:00:02.02200:00:04.76200:00:02.73200:00:03.97200:00:02.66100:00:04.8121700:00:09.36000:00:20.55000:00:11.97300:00:16.98000:00:11.95100:00:21.0601800:00:29.17200:01:09.47000:00:38.13000:00:56.96000:00:38.48800:01:11.5581900:02:33.76100:05:31.83800:03:10.32000:04:34.24000:03:14.55100:05:38.0462000:11:28.82600:18:19.24800:10:12.39000:15:42.78400:10:06.40600:19:01.1502101:19:16.90501:20:06.12100:45:34.475не проверял00:46:46.476не проверял

BitArray - это упоминавшийся в теме System.Collections.BitArray.
BoolArray8, BoolArray16, BoolArray32, BoolArray64 - это мои классы, в которых для упаковки значений bool использовались соответственно byte, short, int, long.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39247461
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Некоторые выводы.

1. Самописные классы существенно эффективнее BitArray
2. Использование для упаковки short приблизительно в полтора раза хуже использования byte, а long - ещё хуже (на 32-битной ОС)
3. Использование byte приблизительно равнозначно использованию int.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39247486
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почти совпало с моими предсказаниями 19228795 . Странный результат с short, проверь что в коде BoolArray16 ничего не напутано. long надо на x64 тестить.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39247889
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Класс BoolArray16:
Код: 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.
    internal class BoolArray16
    {
        short[] values, mask0, mask1;

        public BoolArray16(int _size)
        {
            values = new short[(_size - 1) / 16 + 1];

            mask1 = new short[16];
            mask0 = new short[16];
            for (int i = 0; i < 16; i++)
            {
                mask1[i] = (short)(1 << i);
                mask0[i] = (short)~mask1[i];
            }
        }

        public bool get(int _index)
        {
            return 0 != (values[_index >> 4] & mask1[_index & 15]);
        }

        public void set(int _index, bool _value)
        {
            int valuesIndex = _index >> 4;

            if (_value)
                values[valuesIndex] = (short)(values[valuesIndex] | mask1[_index & 15]);
            else
                values[valuesIndex] = (short)(values[valuesIndex] & mask0[_index & 15]);
        }
    }
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248052
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,
что то меня берут сомнения
у вас на 20
bool[] -00:11:28.826;
BoolArray16 -00:15:42.784
у меня 5 миллисекунд и 20 соответственно
обыкновенный цикл заполнения и считывания?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248081
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Класс BoolArray16:...
Выглядит нормально. Значит в .net что-то недооптимизировано с short

Где-то в степи что то меня берут сомнения
у вас на 20
Не 20 а 2^20, и, как понял, гонял он какой-то свой алгоритм чего-то считающий с интенсивным использованием массива bool[].
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248096
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
я и написал на 20( читать 2^20)
какой может быть алгоритм доступа к массиву?,BoolArray16 - это я вижу
а где код замеров, обычно когда выкладываю таблицу замеров - принято и выкладывать весь механизм замера,
тем более выводить по ним резюме...
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248111
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выкладывать весь алгоритм и его цель я не буду, но суть опишу.
В нескольких параллельно работающих потоках (приблизительно равноправных по объёму работы) создаются массивы значений bool указанного размера. По ходу решения задачи они многократно заполняются по определённой логике и по окончании шага цикла очищаются.

Механизм замера - вызов DateTime.Now в начале работы и DateTime.Subtract() в конце.

Есть, конечно, погрешность, связанная с непостоянной текущей загруженностью компа во время работы.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248121
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И ещё. Если дорисовать в классе public bool this[int index] и обращаться как к элементам массива, то работа замедляется приблизительно на 3%, что для меня не мало.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248131
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степиDima T,
я и написал на 20( читать 2^20)
какой может быть алгоритм доступа к массиву?,BoolArray16 - это я вижу
а где код замеров, обычно когда выкладываю таблицу замеров - принято и выкладывать весь механизм замера,
тем более выводить по ним резюме...
ИМХУ твой тест не показательный. Он очень быстро происходит, а разницу в 10 мс можно просто списать на погрешность измерения. Да и линейный он, что тоже редко встречается в реальной жизни.
Если уж полноценное тестирование устраивать, то надо какой-нибудь долгоиграющий несложный алгоритм, который непоследовательно будет обращаться к разным элементам. Например посчитать количество/сумму всех простых чисел до N Решетом Эратосфена .

А так в целом результаты AR® достаточно показательны, если он менял только тип массива. Правда немного смущает что многопоточно работало.

PS Как подозреваю bool[] становится медленнее когда перестает влазить в кэш проца. Битовый массив в 8 раз меньше памяти занимает. Если так, то тут играет роль не только размер массива, но и остального что в это время используется. Т.е. для разных алгоритмов этот "пограничный" размер будет разный.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248139
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T Правда немного смущает что многопоточно работало.
Подчеркну, что здесь речь про массивы, используемые каждый в своём потоке, к ним нет конкурентного доступа.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248150
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
ну давай возьмем,^30
массив 11 секунд
костыль 23 секунды
замерял наручными часами, или есть желание через песочные?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248233
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степиDima T,
ну давай возьмем,^30
массив 11 секунд
костыль 23 секунды
замерял наручными часами, или есть желание через песочные?
Топик читать не пробовал? Твой результат совпадает с результатом AR® (и моим тоже). BoolArray16 (на short[]) самый тормозной. В 1,5-2 раза медленнее bool[]

Поправил под Int32. Результаты такие
Размерbool[] мсBoolArray32() мсСоотношение100000046150%2000000913144%40000002527108%8000000655686%10000000887282%2000000025415561%4000000061236159%80000000134799274%1000000001736138580%2000000003663324689%4000000007747707591%800000000161701472291%
Исходник. Сумма всех простых решетом Эратосфена
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
		internal sealed class BoolArray32 {
			Int32[] values, mask0, mask1;

			public BoolArray32(Int32 _size)
			{
				values = new Int32[(_size - 1) / 32 + 1];

				mask1 = new Int32[32];
				mask0 = new Int32[32];
				for (int i = 0; i < 32; i++)
				{
					mask1[i] = (1 << i);
					mask0[i] = ~mask1[i];
				}
			}

			public bool this[int index] {
				get {return Get(index); }
				set {Set(index,value); }
			}

			public bool Get(int _index)
			{
				return 0 != (values[_index >> 5] & mask1[_index & 31]);
			}

			public void Set(int _index, bool _value)
			{
				int valuesIndex = _index >> 5;

				if (_value)
					values[valuesIndex] |= mask1[_index & 31];
				else
					values[valuesIndex] &= mask0[_index & 31];
			}
	    }

		static Int64 Eratosfen(Int32 len) {
			Console.Write("Test " + len);
			var sw = Stopwatch.StartNew();
			Int64 sum = 0;
// закаментить ненужное
			//var s = new bool[len];
			var s = new BoolArray32(len);
			s[0] = true;
			s[1] = true;
			Int32 found = 0;
			while(found < len) {
				sum += found;
				while(found < len && s[found]) found++; // Следующее простое
				for(Int32 i = found; i < len; i += found) s[i] = true;
			}
			Console.WriteLine(" result " + sum + " Time " + sw.ElapsedMilliseconds + " ms");

			return sum;
		}

		static void Main(string[] args) {
			Eratosfen(1000000);
			Eratosfen(2000000);
			Eratosfen(4000000);
			Eratosfen(8000000);
			Eratosfen(10000000);
			Eratosfen(20000000);
			Eratosfen(40000000);
			Eratosfen(80000000);
			Eratosfen(100000000);
			Eratosfen(200000000);
			Eratosfen(400000000);
			Eratosfen(800000000);
			return;
		}

...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248317
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Dima T Правда немного смущает что многопоточно работало.
Подчеркну, что здесь речь про массивы, используемые каждый в своём потоке, к ним нет конкурентного доступа.
Я о другом. Допустим есть 4 потока, запускаются одновременно, ты меришь по последнему, предположим в одном случае последним заканчивает например 1-й, в другом 3-й. В итоге получается ерунда: замеры двух разных расчетов (на разных исходных данных). Другой момент - включен гипертрейдинг на проце, например два потока могу оказаться на одном реальном ядре, а могут на двух разных. Тут тоже заметная разница будет. 2-хядерный проц с HT (виндовс показывает как 4 ядра) реально работает с производительностью максимум ~2,5 ядра, т.е. 4 потока в 2,5 раза быстрее чем 1, но 2 потока в 2 раза быстрее. (при условии что синхронизация не требуется)
Не утверждаю что у тебя что-то из описанного было, я к тому что для чистоты эксперимента замеры лучше делать однопоточно.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248333
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я делал столько потоков, сколько возвращает Environment.ProcessorCount. У меня это 4.
По ходу экспериментов выяснилось, что диспетчер задач показывает загрузку прямо пропорционально количеству "вычислительных" потоков (если их <=4), т.е. для 1 потока - 25%, 2 - 50 %, 3 - 75 %, 4 - 99%.
Т.е. можно считать, что каждый поток всё-таки оказывается в отдельном ядре.

И ещё интересно, что диспетчер задач показывает для моей программы общее число потоков 9. При 4 запущенных мной явно это означает, что в 5 потоках "живёт" единственное окно с полями и кнопкой?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248362
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Я делал столько потоков, сколько возвращает Environment.ProcessorCount. У меня это 4.
По ходу экспериментов выяснилось, что диспетчер задач показывает загрузку прямо пропорционально количеству "вычислительных" потоков (если их <=4), т.е. для 1 потока - 25%, 2 - 50 %, 3 - 75 %, 4 - 99%.
Т.е. можно считать, что каждый поток всё-таки оказывается в отдельном ядре.
ОС (в т.ч. диспетчер задач) показывает загрузку логических процов, а не реальных, т.е. при включенном Hyper-threading половина процов "муляж".
Например на 4-хядерном i7 без гипертрейдинга 4 потока считают в 4 раза быстрее чем один, на 2-хядерном i5 c гипертрейдингом - в 2,5 раза. Хотя в обоих случаях диспетчер честно показывает 4 логических проца загруженных на 100%.

AR®И ещё интересно, что диспетчер задач показывает для моей программы общее число потоков 9. При 4 запущенных мной явно это означает, что в 5 потоках "живёт" единственное окно с полями и кнопкой?
Это пул потоков заранее создал запасные, на случай если что-то асинхронно надо будет выполнять.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248371
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На моём компе до размера массивов 2^17 наблюдалось довольно чёткое учетверение при переходе от 1 потока к 4.
При 2^18 и 2^19 - ближе к утроению, дальше - ближе к удвоению.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248420
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®На моём компе до размера массивов 2^17 наблюдалось довольно чёткое учетверение при переходе от 1 потока к 4.
При 2^18 и 2^19 - ближе к утроению, дальше - ближе к удвоению.
Проц какой? Сколько реальных ядер?

Тут еще такой момент есть: расчет должен быть поделен между потоками равномерно. Может оказаться что стартуют все 4 одновременно, но один работает секунду, второй - две, третий - 3, 4-й - четыре. В итоге общее время 10 секунд, но отработало за 4 (максимальное), хотя в идеале должно быть 2,5 (10/4). Ну и Закон Амдала мешает если есть хоть мало-мальская синхронизация.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248675
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Intel Core i3-2120 @ 3,3 ГГц.

Диспетчер устройств показывает четыре процессора, а сколько реальных ядер, я не знаю.
Работа разделена между потоками достаточно поровну, а синхронизации между потоками нет за ненадобностью.
Есть "взаимопомощь" между потоками, когда побочный результат работы одного потока снимает часть работы с другого, что и вынудило копать в сторону ConcurrentDictionary.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248698
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®сколько реальных ядер, я не знаю.
http://ark.intel.com/ru/products/53426/Intel-Core-i3-2120-Processor-3M-Cache-3_30-GHz
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248699
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Intel Core i3-2120 @ 3,3 ГГц.

Диспетчер устройств показывает четыре процессора, а сколько реальных ядер, я не знаю.
На сайте интела все написано Intel Core i3-2120 . Реальных 2 ядра у тебя.
На расчетных задачах максимум ускорения в 2,5 раза, при полной загрузке всех логических процов на 100%

AR®Работа разделена между потоками достаточно поровну, а синхронизации между потоками нет за ненадобностью.
Есть "взаимопомощь" между потоками, когда побочный результат работы одного потока снимает часть работы с другого, что и вынудило копать в сторону ConcurrentDictionary.
Если есть какие-то промежуточные результаты необходимые разным потокам, то может есть смысл сами результаты кэшировать. Т.е. досчитал до места, которое возможно уже посчитано, заглянул в кэш, если есть - взял, если нет - посчитал, записал в кэш. Кэш делать тем же ConcurrentDictionary, а внутри как есть оставить. Тут алгоритм надо смотреть, что кэшировать и сколько места под кэш надо.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39248766
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕсли есть какие-то промежуточные результаты необходимые разным потокам, то может есть смысл сами результаты кэшировать. Т.е. досчитал до места, которое возможно уже посчитано, заглянул в кэш, если есть - взял, если нет - посчитал, записал в кэш. Кэш делать тем же ConcurrentDictionary, а внутри как есть оставить.

Именно так всё и сделано с самого начала. Только с ростом размера данных пришлось отказаться от ConcurrentDictionary в пользу BitArray и lock{}.


Попутно поделюсь ещё одним открытием, про которое не знают даже в MS :)
Замена кода
Код: c#
1.
2.
                values[valuesIndex] = values[valuesIndex] | mask1[_index & 31];
                values[valuesIndex] = values[valuesIndex] & mask0[_index & 31];


на
Код: c#
1.
2.
                values[valuesIndex] |= mask1[_index & 31];
                values[valuesIndex] &= mask0[_index & 31];



в моём BoolArray32 не приводит ни к чему, а аналогичная в BoolArray8, BoolArray16 - к потере скорости на 15-20 %
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39249244
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Именно так всё и сделано с самого начала. Только с ростом размера данных пришлось отказаться от ConcurrentDictionary в пользу BitArray и lock{}.
Я другое предлагал. Делаешь копию и потом ее добавляешь в кэш. Соответственно при чтении из кэша копию с кэша. Т.к. сама копия в кэше не меняется, то для доступа к ней блокировок не надо. Для экономии памяти можно пожать при записи в кэш.
Т.е. кэш это ConcurrentDictionary<KEY, BoolArray32> где KEY какой-то тип отражающий общее состояние BoolArray32.

Раз уж начали - затестил разные блокировки. У меня получается с Interlocked в 3 раза медленнее, с Lock в 7 раз медленнее чем без блокировок.
Исходник
Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
		internal sealed class BoolArray32 {
			Int32[] values, mask0, mask1;
			Object _lock = new object();

			public BoolArray32(Int32 _size)
			{
				values = new Int32[(_size - 1) / 32 + 1];

				mask1 = new Int32[32];
				mask0 = new Int32[32];
				for (int i = 0; i < 32; i++)
				{
					mask1[i] = (1 << i);
					mask0[i] = ~mask1[i];
				}
			}

			public bool this[int index] {
				get {return Get(index); }
				set {Set(index,value); }
			}

			public bool Get(int _index)
			{
				return 0 != (values[_index >> 5] & mask1[_index & 31]);
			}

			public void Set(int _index, bool _value)
			{
				if (_value)
					values[_index >> 5] |= mask1[_index & 31];
				else
					values[_index >> 5] &= mask0[_index & 31];
			}

			public void SetInterlocked(int _index, bool _value) {
				Int32 cur, val;
				do {
					cur = values[_index >> 5];
					if (_value) {
						val = cur | mask1[_index & 31];
					} else {
						val = cur & mask0[_index & 31];
					}
				} while (cur != val && cur != Interlocked.CompareExchange(ref values[_index >> 5], val, cur));
			}

			public void SetLock(int _index, bool _value) {
				if(Get(_index) == _value) return;
				lock(_lock) {
					if (_value)
						values[_index >> 5] |= mask1[_index & 31];
					else
						values[_index >> 5] &= mask0[_index & 31];
				}
			}


		}

		static Int64 Eratosfen(Int32 len) {
			GC.Collect();
			Console.Write("Test " + len);
			var sw = Stopwatch.StartNew();
			Int64 sum = 0;
			var s = new BoolArray32(len);
			s.Set(0, true);
			s.Set(1, true);
			Int32 found = 0;
			while(found < len) {
				sum += found;
				while(found < len && s[found]) found++; // Следующее простое
				for(Int32 i = found; i < len; i += found) s.Set(i, true);
			}
			Console.WriteLine(" result " + sum + " Time " + sw.ElapsedMilliseconds + " ms");
			return sum;
		}

		static Int64 EratosfenLock(Int32 len) {
			GC.Collect();
			Console.Write("Test Lock " + len);
			var sw = Stopwatch.StartNew();
			Int64 sum = 0;
			var s = new BoolArray32(len);
			s.SetLock(0, true);
			s.SetLock(1, true);
			Int32 found = 0;
			while(found < len) {
				sum += found;
				while(found < len && s[found]) found++; // Следующее простое
				for(Int32 i = found; i < len; i += found) s.SetLock(i, true);
			}
			Console.WriteLine(" result " + sum + " Time " + sw.ElapsedMilliseconds + " ms");
			return sum;
		}

		static Int64 EratosfenInterlocked(Int32 len) {
			GC.Collect();
			Console.Write("Test Interlocked " + len);
			var sw = Stopwatch.StartNew();
			Int64 sum = 0;
			var s = new BoolArray32(len);
			s.SetInterlocked(0, true);
			s.SetInterlocked(1, true);
			Int32 found = 0;
			while(found < len) {
				sum += found;
				while(found < len && s[found]) found++; // Следующее простое
				for(Int32 i = found; i < len; i += found) s.SetInterlocked(i, true);
			}
			Console.WriteLine(" result " + sum + " Time " + sw.ElapsedMilliseconds + " ms");

			return sum;
		}

		static void Main(string[] args) {
			Eratosfen(1000000);
			EratosfenInterlocked(1000000);
			EratosfenLock(1000000);
			Eratosfen(2000000);
			EratosfenInterlocked(2000000);
			EratosfenLock(2000000);
			Eratosfen(4000000);
			EratosfenInterlocked(4000000);
			EratosfenLock(4000000);
			Eratosfen(8000000);
			EratosfenInterlocked(8000000);
			EratosfenLock(8000000);
			return;
}

...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39249951
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДелаешь копию и потом ее добавляешь в кэш. Соответственно при чтении из кэша копию с кэша. Т.к. сама копия в кэше не меняется, то для доступа к ней блокировок не надо. Для экономии памяти можно пожать при записи в кэш.

Понял. Только для моего случая это вряд ли оправданно. В том смысле, что общее время работы вырастет. А проблему нехватки памяти процессу я "надолго"(думаю, до 2^31) решил использованием BoolArray32.

Не совсем понял "трюка" с _lock (формальным объектом?) в последней версии решета Эратосфена. Для lock всё равно что ли, что будет у него в ()? Можно пояснить?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250009
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Не совсем понял "трюка" с _lock (формальным объектом?) в последней версии решета Эратосфена. Для lock всё равно что ли, что будет у него в ()? Можно пояснить?
Скопипастил откуда-то, можно было написать lock(values).
В остальном без разницы какой объект блокировать, главное чтобы все места кода блокировали один и тот же объект.
Т.е. блокировка это по сути флаг, установить который может только один поток, второй (при попытке установить) будет ждать пока первый закончит.
Если кратко, алгоритм использования блокировок такой: установить флаг, поработать со всеми объектами которые он защищает, снять флаг. Т.е. не надо 10 блокировок для 10 взаимосвязанных объектов, достаточно одной.
Почитай Рихтера, глава "Класс Monitor и блоки синхронизации" там подробно расписано как это устроено.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250025
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПочитай Рихтера, глава "Класс Monitor и блоки синхронизации" там подробно расписано как это устроено.
Лучше про ReaderWriterLockSlim
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250188
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решил пока сосредоточиться на оптимизациях самого алгоритма и задумался: конструкция вида
Код: c#
1.
values = new int[valuesSize]; 


гарантирует инициализацию всего массива нулями?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250195
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Решил пока сосредоточиться на оптимизациях самого алгоритма и задумался: конструкция вида
Код: c#
1.
values = new int[valuesSize]; 


гарантирует инициализацию всего массива нулями?
Да.
Не совсем то, но похожий случай https://msdn.microsoft.com/ru-ru/library/0a7fscd0.aspx
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250198
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
интересно, насколько быстрее будет аккуратно написанное на С
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250221
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Интересно, что тогда более правильно делать много (миллионы) раз за время выполнения программы
Код: c#
1.
2.
3.
values = null;
GC.Collect();
values = new int[valuesSize]; 


или
Код: c#
1.
2.
3.
            
for (int i = 0; i < valuesSize; i++)
    values[i] = 0;



Изопропилинтересно, насколько быстрее будет аккуратно написанное на С
Тут весь вопрос, на каком C, и чем он будет скомпилирован. Вы, возможно, имели ввиду, что результат будет не под .Net ?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250267
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Вы, возможно, имели ввиду, что результат будет не под .Net ?
естесnвенно без dotnet

а с компиляторами вариантов немного - MSVC и gcc
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250270
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилинтересно, насколько быстрее будет аккуратно написанное на С
Если совсем без проверок на корректность параметров, то результаты такие (MSVC2015 x86)
Размерc# мсc++ мсОтношение10000006350%200000013862%4000000271763%8000000563664%10000000724563%2000000015510568%4000000036125170%8000000099269770%100000000138597971%2000000003246252878%4000000007075555378%800000000147221205782%
Исходник
Код: plaintext
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>

class BoolArray32 {
	int* values;
	int mask0[32], mask1[32];

public:

	BoolArray32(int _size)
	{
		values = (int*) calloc((_size - 1) / 32 + 1, sizeof(int));

		for (int i = 0; i < 32; i++)
		{
			mask1[i] = (1 << i);
			mask0[i] = ~mask1[i];
		}
	}

	~BoolArray32() {
		free(values);
	}

	bool Get(int _index)
	{
		return 0 != (values[_index >> 5] & mask1[_index & 31]);
	}

	void Set(int _index, bool _value)
	{
		if (_value)
			values[_index >> 5] |= mask1[_index & 31];
		else
			values[_index >> 5] &= mask0[_index & 31];
	}
};

int64_t Eratosfen(int len) {
	printf("Test %d" , len);
	clock_t t = clock();
	int64_t sum = 0;
	BoolArray32 s(len);
	s.Set(0, true);
	s.Set(1, true);
	int found = 0;
	while (found < len) {
		sum += found;
		while (found < len && s.Get(found)) found++; // Следующее простое
		for (int i = found; i < len; i += found) s.Set(i, true);
	}
	printf(" result %lld Time %d ms\n", sum, clock() - t);
	return sum;
}

int main(int argc, char**argv)
{
	Eratosfen(1000000);
	Eratosfen(2000000);
	Eratosfen(4000000);
	Eratosfen(8000000);
	Eratosfen(10000000);
	Eratosfen(20000000);
	Eratosfen(40000000);
	Eratosfen(80000000);
	Eratosfen(100000000);
	Eratosfen(200000000);
	Eratosfen(400000000);
	Eratosfen(800000000);
	return 0;
}

...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250282
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Интересно, что тогда более правильно делать много (миллионы) раз за время выполнения программы
Код: c#
1.
2.
3.
values = null;
GC.Collect();
values = new int[valuesSize]; 


или
Код: c#
1.
2.
3.
            
for (int i = 0; i < valuesSize; i++)
    values[i] = 0;


ИМХУ второе. Но затести, может для твоего случая первое окажется быстрее.

Тут еще учитывай тот момент что запуск сборки мусора останавливает все потоки.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250285
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и это
Код: c#
1.
2.
for (int i = 0; i < valuesSize; i++)
    values[i] = 0;


в книжках рекомендуют писать так
Код: c#
1.
2.
for (int i = 0; i < values.Length; i++)
    values[i] = 0;


утверждают так работает быстрее. Объясняют тем что компилятор убирает проверку индекса на выход за границы массива.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250297
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
[src c#]
for (int i = 0; i < valuesSize; i++)
values[i] = 0;



Обычно делают что то типа
[src c#]
for (int i = 0; i < valuesSize; i++++)
values[i] = 0;
values[i+1] = 0;

[/quot]
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250306
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ, вот что Рихтер пишет по этому поводу
Внутренняя реализация массивов...Кроме того, в общем случае компилятор умеет выносить код проверки границ за пределы цикла. К примеру, рассмотрим следующий код:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
using System;
public static class Program {  
  public static void Main() {    
    Int32[] a = new Int32[5];
    for(Int32 index = 0; index < a.Length; index++) {
       // Какие-то действия с элементом a[index]
    }
  }
 } 


Обратите внимание на вызов свойства Length в проверочном выражении цикла for. Фактически при этом вызывается метод, но JIT-компилятор «знает», что Length является свойством класса Array, поэтому создает код, в котором метод вызывается всего один раз, а полученный результат сохраняется в промежуточной переменной. Именно ее значение проверяется на каждой итерации цикла. В результате такой код работает очень быстро. Некоторые разработчики недооценивают возможности JIT-компилятора и пишут «умный код», пытаясь помочь его работе. Однако такие попытки практически всегда приводят к снижению производительности, а также делают готовую программу непонятной и неудобной для редактирования. Поэтому пусть свойство Length вызывается автоматически.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250505
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

замена BoolArray32 на BoolArray64 дала серьёзный позитивный эффект (с++)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250554
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima T,

замена BoolArray32 на BoolArray64 дала серьёзный позитивный эффект (с++)
x86 или x64 ?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250578
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИзопропилDima T,

замена BoolArray32 на BoolArray64 дала серьёзный позитивный эффект (с++)
x86 или x64 ?
ошибка закралась...

ничего не помогает. inline, замена маски на сдвиг, Set(,true) без ветвления.
машинный код чистый, всё что можно на регистрах.

потеря в 20% - наверное неплохой результат для dotnet
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39250655
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилпотеря в 20% - наверное неплохой результат для dotnet
На самом деле еще меньше. Пробовал в код С++ добавить контроль выхода индекса за пределы - время лучше на 10-15% по сравнению с C#. Так что результат очень даже неплохой.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39251126
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tв книжках рекомендуют писать так

Код: c#
1.
2.
for (int i = 0; i < values.Length; i++)
    values[i] = 0;



утверждают так работает быстрее. Объясняют тем что компилятор убирает проверку индекса на выход за границы массива.

Категорически опровергаю . Потеря общего времени работы 3-5%, причём устойчиво повторяющаяся.

Изопропилзамена BoolArray32 на BoolArray64 дала серьёзный позитивный эффект (с++)
На C# только проигрыш, что на 32-, что на 64-битной ОС.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39251179
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВОбычно делают что то типа
Код: c#
1.
2.
3.
4.
5.
for (int i = 0; i < valuesSize; i++++)
{
    values[i] = 0;
    values[i+1] = 0;
}





Результат, увы, не лучше. Даже если написать values[i] = values[i+1] = 0;
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39251184
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®, Array.Clear(arr, 0, arr.Length) также?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39251323
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
buser Array.Clear(arr, 0, arr.Length)

Вроде как чуть быстрее, чем свой явный for() всех испытанных разновидностей. Спасибо.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39252838
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё вести с полей, из разряда о чём не знал Марти Стауффер :)

В какой-то момент сообразил, что в моём алгоритме нигде не требуется сбрасывать отдельный элемент в BoolArray32 в false, а только устанавливать в true.
И написал вместо
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
        public void set(int _index, bool _value)
        {
            int valuesIndex = _index >> 5;  

            if (_value)
                values[valuesIndex] |= mask1[_index & 31];    
            else
                values[valuesIndex] &= mask0[_index & 31];   
        }



сначала
Код: c#
1.
2.
3.
4.
5.
6.
        public void settrue(int _index)
        {
            int valuesIndex = _index >> 5;  

            values[valuesIndex] |= mask1[_index & 31]; 
        }



а потом
Код: c#
1.
2.
3.
4.
        public void settrue(int _index)
        {
            values[_index >> 5] |= mask1[_index & 31]; 
        }


(и звал settrue() вместо set() )

Первая "оптимизация" приводит к потере времени ~на 15%, вторая ещё на 2-4%
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253490
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Первая "оптимизация" приводит к потере времени ~на 15%, вторая ещё на 2-4%
странно это всё....
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253524
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,
ггыгы)))
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253747
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Было бы смешно, кабы не было так грустно.
Единицы процентов на длительностях порядка суток дают затраты порядка часов.
Поэтому экспериментирую с "мелочами".
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253752
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,

ничего смешного,
для отжимания процентов лучше c/c++
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253800
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выносить основную работу в dll ? А как быть с многопоточностью?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253829
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Выносить основную работу в dll ? А как быть с многопоточностью?
нет никаких проблем с многопоточностью.

PS эксперименты с выносом счётной части в c/с++ я бы начинал только после написания оного на c#
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39253975
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,
те не кажется что это клон стебелька со своими бенчмарками
зы проблема многопоточности и тестировании производительности в разных потоках легко лечится галоперидолом..
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254047
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилэксперименты с выносом счётной части в c/с++ я бы начинал только после написания оного на c#
Да я считаю, что оно уже написано.

По сравнению с использованием ConcurrentDictionary / bool[] время работы улучшилось примерно вдвое, и стала в принципе возможной работа на больших данных, для которой в исходных версиях не хватало памяти.
Дальнейшая оптимизация, по моему разумению, возможна только в направлении накладывания более "узких" блокировок отдельными потоками, чтобы они меньше задерживали друг друга.

Не под .net я писал на C лет 8 назад последний раз в VS98 (dll для Crystal Reports).
Честно говоря, какая технология должна быть сейчас (VS2010 или VS2015), что бы родился не управляемый код, я не знаю.

Где-то в степипроблема многопоточности и тестировании производительности в разных потоках легко лечится галоперидолом
А чем лечится заинтересованность в результатах своего труда и стремление сделать их лучше? По вашей логике, аминазином? Солями лития? Электросудорожной терапией?
Могу, к слову сказать, чем устраняются видения "клонов с бенчмарками". По русской традиции надо перекреститься, а главное устранить источник раздражения. То есть: не интересно вам всё это, так не читайте и не пишите сюда.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254049
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилэксперименты с выносом счётной части в c/с++ я бы начинал только после написания оного на c# С использованием unsafe и указателей.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254050
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Честно говоря, какая технология должна быть сейчас (VS2010 или VS2015), что бы родился не управляемый код, я не знаю.

no comments
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254054
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,
"Ты играй, моя гитара, Говори ещё." ©
))
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254067
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КИзопропилэксперименты с выносом счётной части в c/с++ я бы начинал только после написания оного на c# С использованием unsafe и указателей.
Спасибо, я сразу не понял, что именно это имелось ввиду.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254076
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Алексей Кпропущено...
С использованием unsafe и указателей.
Спасибо, я сразу не понял, что именно это имелось ввиду.
я эту чушь ввиду не имел
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254091
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилAR®пропущено...

Спасибо, я сразу не понял, что именно это имелось ввиду.
я эту чушь ввиду не имелНу если работа с массивами без проверки границ в контексте дефицита процессорных ресурсов - чушь, то Бог тебе судья. :-)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254095
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНу если работа с массивами без проверки границ в контексте дефицита процессорных ресурсов - чушь, то Бог тебе судья. :-)
в случае дефицита процессорных ресурсов применяется с++

jit нынче умеет так? (vector<bool> имеет специализацию, велосипед не нужен)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
while (found < len && s[found] ) found++; // Следующее простое
00007FF795611096  cmp         eax,edi  
00007FF795611098  jge         Eratosfen+0C5h (7FF7956110C5h)  
00007FF79561109A  nop         word ptr [rax+rax]  
00007FF7956110A0  movsxd      rdx,eax  
00007FF7956110A3  mov         rcx,rdx  
00007FF7956110A6  shr         rcx,5  
00007FF7956110AA  lea         r8,[rbx+rcx*4]  
00007FF7956110AE  movzx       ecx,dl  
00007FF7956110B1  and         cl,1Fh  
00007FF7956110B4  movzx       edx,cl  
00007FF7956110B7  mov         ecx,dword ptr [r8]  
00007FF7956110BA  bt          ecx,edx  
00007FF7956110BD  jae         Eratosfen+0C5h (7FF7956110C5h)  
00007FF7956110BF  inc         eax  
00007FF7956110C1  cmp         eax,edi  
00007FF7956110C3  jl          Eratosfen+0A0h (7FF7956110A0h)  
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254100
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не буду втягиваться в срач. Привык на форумах узнавать что-то полезное и делиться полезным.
В ряде задач требуется посчитать вес Хэмминга для числа - количество 1 в его двоичном представлении. Следующий код показал наилучшее время работы среди 7 испытанных вариантов (C# VS2010, wrk - "взвешиваемое" число, bits - результат):
Код: c#
1.
for(bits = 0; wrk != 0; bits++, wrk &= (wrk - 1));



За сим - всё.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254106
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилАлексей КНу если работа с массивами без проверки границ в контексте дефицита процессорных ресурсов - чушь, то Бог тебе судья. :-)
в случае дефицита процессорных ресурсов применяется с++

jit нынче умеет так? (vector<bool> имеет специализацию, велосипед не нужен)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
while (found < len && s[found] ) found++; // Следующее простое
00007FF795611096  cmp         eax,edi  
00007FF795611098  jge         Eratosfen+0C5h (7FF7956110C5h)  
00007FF79561109A  nop         word ptr [rax+rax]  
00007FF7956110A0  movsxd      rdx,eax  
00007FF7956110A3  mov         rcx,rdx  
00007FF7956110A6  shr         rcx,5  
00007FF7956110AA  lea         r8,[rbx+rcx*4]  
00007FF7956110AE  movzx       ecx,dl  
00007FF7956110B1  and         cl,1Fh  
00007FF7956110B4  movzx       edx,cl  
00007FF7956110B7  mov         ecx,dword ptr [r8]  
00007FF7956110BA  bt          ecx,edx  
00007FF7956110BD  jae         Eratosfen+0C5h (7FF7956110C5h)  
00007FF7956110BF  inc         eax  
00007FF7956110C1  cmp         eax,edi  
00007FF7956110C3  jl          Eratosfen+0A0h (7FF7956110A0h)  

Головняки с интеграцией C# <=> C++ на пустом месте тоже ни к чему. Нужно искать компромисс, которым вполне может стать unsafe C#. Стоит как минимум упомянуть об этой возможности на совещании по вопросам оптимизации.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254108
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Не буду втягиваться в срач.Тут срачей нет уже лет пять, если не больше.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254130
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,
вообще, разговор нужно начинать для чего, если просто изЪебнуться, то и нативный массив подойдет, вообще контейнеров для коллекций в дот нете написано нисколько десятков тысяч ( что я встречал), вопрос для чего.?
зы да вектор ++ перегружен под bool по темплейту как значение бит , по смысловой идентификации как bitarray, есть доступ по индексу без поверки на выход, есть и at - с проверкой на выход..
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254145
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степивообще контейнеров для коллекций в дот нете написано нисколько десятков тысяч ( что я встречал)И только применение unsafe и указателей позволяет в C# работать с массивами без проверки границ, что позволяет повысить производительность в 1.5 ... 3 раза, приближаясь вплотную к С++. Это по моим наблюдениям на тестах вроде пузырьковой сортировки.
Где-то в степивопрос для чего.?Для снижения процессорной нагрузки, как мне показалось.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254178
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,
куда вы денете уборщик мусора? его то же нах под фиксед?)) если у вас возникла такая проблема то вы выбрали не тот язык
зы хотя я видел что и уборщика посылали нах, в технологии disruptor, java, ну какая разница, ну там хоть перегрузку системы делали раз в сутки.
В два раза из за if - не поверю, тогда бы и народ визжал что this в объектных методах проверяется на( не всегда) нулл
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254625
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степикуда вы денете уборщик мусора? его то же нах под фиксед?))Памяти у нас много. Чё её экономить?
Где-то в степиесли у вас возникла такая проблема то вы выбрали не тот языкИли не те алгоритмы, или не ту архитектуру. Тут проще всего взять, и написать на C++, добавив при этом архитектурного геморроя с интеграциями и необходимостью компиляции под конкретный процессор.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254640
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кдобавив при этом архитектурного геморроя с интеграциями
вряд ли сложнее чем с Direct3D будет
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254662
void33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алексей К,
авторПамяти у нас много. Чё её экономить?
какой памяти? я говорю в контексте быстродействия, причем тут память?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254745
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилАлексей Кдобавив при этом архитектурного геморроя с интеграциями
вряд ли сложнее чем с Direct3D будетМожет быть.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254750
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
void33Алексей К,
авторПамяти у нас много. Чё её экономить?
какой памяти?Оперативной.

void33я говорю в контексте быстродействия, причем тут память?При том, что сборка мусора вообще может не произойти. Всякое может быть.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254777
void33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алексей К,
авторПри том, что сборка мусора вообще может не произойти. Всякое может быть
хоспади, да оставьте вы котов шредингеру, вашей с.. сотировки пузырьком может и ваще не понадобиться, есть куча стандартных решений.
уборка мусора и оперативная память гы гы, более убогой ассоциации и не придумаешь, может вы еще свяжете
оutоfмemory и оперативную память?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254787
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
void33Алексей К,
авторПри том, что сборка мусора вообще может не произойти. Всякое может быть
хоспади, да оставьте вы котов шредингеру, вашей с.. сотировки пузырьком может и ваще не понадобиться, есть куча стандартных решений.
уборка мусора и оперативная память гы гы, более убогой ассоциации и не придумаешь, может вы еще свяжете
оutоfмemory и оперативную память?Не вижу почвы для беспокойства. Я всего лишь предложил перед отказом от C# в пользу C++ окончательно убедиться в том, что все возможности C# были полностью использованы, что переход на C++ действительно оправдан.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254811
void33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алексей К,
какие возможности? приведите хоть один пример. написание драйверов? дак для этого высокоуровневый ассемблер существует.
просто этот топик вакханалия безумных доморощенных программистов.
1 Ограничение на размер объекта, оно одинаковы для 32 и 64
2 Как снять это ограничение декларативно под 64
3 Что такое память процесса.
4 что такое оutоfмemory. оно не как не относится к оперативной памяти, ну разве что если все страницы памяти процессов помечены битом не выгружаемые, то вставить новую при прерывании загрузки страницы не получается (и то для юникс)
и т.д.
зы и ешо вы тут ассоциировали уборщика и оперативную память ..
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254816
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
void33Алексей К,
какие возможности? приведите хоть один пример. написание драйверов? дак для этого высокоуровневый ассемблер существует.
просто этот топик вакханалия безумных доморощенных программистов.
1 Ограничение на размер объекта, оно одинаковы для 32 и 64
2 Как снять это ограничение декларативно под 64
3 Что такое память процесса.
4 что такое оutоfмemory. оно не как не относится к оперативной памяти, ну разве что если все страницы памяти процессов помечены битом не выгружаемые, то вставить новую при прерывании загрузки страницы не получается (и то для юникс)
и т.д.
зы и ешо вы тут ассоциировали уборщика и оперативную память ..

понос какой-то
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254818
void33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
обоснуй
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254825
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
void33,

п 3 - что сказать хотел?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254827
void33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
да хотя бы сколько памяти для процесса гарантирует виндовс ну хотя бы для 32
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254833
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
void33Изопропил,
да хотя бы сколько памяти для процесса гарантирует виндовс ну хотя бы для 32
памяти или адресного пространства?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254835
void33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
памяти
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39254971
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
void33Изопропил,
памяти
20 страниц (MinimumWorkingSetSize)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39256226
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Изопропилэксперименты с выносом счётной части в c/с++ я бы начинал только после написания оного на c#
Да я считаю, что оно уже написано.

По сравнению с использованием ConcurrentDictionary / bool[] время работы улучшилось примерно вдвое, и стала в принципе возможной работа на больших данных, для которой в исходных версиях не хватало памяти.
Дальнейшая оптимизация, по моему разумению, возможна только в направлении накладывания более "узких" блокировок отдельными потоками, чтобы они меньше задерживали друг друга.
Есть еще направление оптимизации: уменьшение количества блокировок, т.к. блокировка сама по себе тяжелая операция. Например мой пример выше при добавлении блокировок замедляется в разы, хотя ожиданий никаких не происходит т.к. работа в один поток. Тут надо строить алгоритм так чтобы было минимум вызовов блокировок, т.е. поток получил крупный кусок данных и дальше работает с ним, а блокировки только для получения этих кусков.

Есть еще такой момент как синхронизация на уровне ядер проца: т.е. формально потоки обращаются к разным участкам памяти, но физически оба участка оказываются в одном блоке памяти (64 байта если не путаю) в итоге происходит постоянная синхронизация кэшей ядер, что замедляет оба потока. У Рихтера есть пример такого случая с замерами времени.

Есть еще такой момент как кэши процессора: если большая часть данных большую часть времени оказывается в кэше (т.е. минимум подкачки из памяти), то ускорение будет до двух раз. Например можно проходить по большому массиву много раз от начала до конца (как в моем примере), а можно перестроить алгоритм и обрабатывать фрагментами по 8-16 Кб. Второй вариант будет заметно быстрее, но алгоритм усложнится.

ИМХУ самое перспективное направление это именно адаптация алгоритма под многопоточность, а не попытка усовершенствовать блокировками однопоточный алгоритм.
AR®Не под .net я писал на C лет 8 назад последний раз в VS98 (dll для Crystal Reports).
Честно говоря, какая технология должна быть сейчас (VS2010 или VS2015), что бы родился не управляемый код, я не знаю.
Как показали тесты выше - портированием на С/С++ большого прироста не получишь. 5-15% максимум. Но напишешься вдоволь, т.к. там разных граблей намного больше чем в C#.
Если надо чтобы было быстрее, то компилятор лучше брать посвежее, т.к. все процессоры разные. Например VS98 по умолчанию компилирует под пентиум 1, а VS2015 под третий.
Есть разница даже в процах одного года выпуска: например топовые версии процов Intel поддерживают набор команд AVX, код скомпилированный с их использованием работает быстрее, но вообще не работает если проц не поддерживает AVX.
Ну и на компиляторах от МС жизнь не заканчивается. Есть другие, компиляция которыми может работать быстрее.

И третий вариант: если добавление памяти ускоряет работу, то разобраться как задействовать максимум имеющейся памяти в режиме x64. Ну и памяти в комп докупить до максимума.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39256382
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фанаты оптимизации оставили без внимания один немаловажный момент.
Сделайте класс структуруй и повторите замер. можете ещё ~10% выигратъ
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39256699
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikron,

Какие структуры - битовый вектор обсуждаем
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39256786
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как ни странно, но ускорение от структуры есть.

class мсstruct мсДоля4000000272489%4000000034731490%4000000007041675696%
Я как понимаю массивы это ссылочные типы, передачи самой структуры куда-либо в параметрах нет, т.е. тут применение структур не должно влиять на скорость, но ускорение есть. ХЗ почему.
ИсходникЦеликом тут 19246254
Заменить
Код: c#
1.
internal sealed class BoolArray32 {


на
Код: c#
1.
internal struct BoolArray32 {

...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39256956
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На моей мащине дало похти 2х кратное улутщение с 600мс на 230мс

Код: 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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
		internal struct BoolArray32 {
			uint[] values;
			public BoolArray32(int _size)
			{
                values = new uint[(_size - 1) / 32 + 1];
			}

            public bool Get(int _index)
            {
                return 0 < (values[_index >> 5] & (1U << (_index & 31)));
            }

            public void Set(int _index)
            {
                values[_index >> 5] |= 1U << (_index & 31);
            }
	    }

        class Programm
        {
            static Int64 Eratosfen(Int32 len)
            {
                Console.Write("Test " + len);
                var sw = Stopwatch.StartNew();
                Int64 sum = 0;
                var s = new BoolArray32(len);
                s.Set(0);
                s.Set(1);
                Int32 found = 0;
                while (found < len)
                {
                    sum += found;
                    while (found < len && s.Get(found)) found++; // Следующее простое
                    for (Int32 i = found; i < len; i += found) s.Set(i);
                }
                Console.WriteLine(" result " + sum + " Time " + sw.ElapsedMilliseconds + " ms");

                return sum;
            }

            static void Main(string[] args)
            {
                //Eratosfen(1000000);
                //Eratosfen(2000000);
                Eratosfen(4000000);
                //Eratosfen(8000000);
                //Eratosfen(10000000);
                //Eratosfen(20000000);
                //Eratosfen(40000000);
                //Eratosfen(80000000);
                //Eratosfen(100000000);
                //Eratosfen(200000000);
                //Eratosfen(400000000);
                //Eratosfen(800000000);
                Console.ReadLine();
                return;
            }
        }

Dima T,
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39256963
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таким образом отставание от С++ дол+но составлятъ не более 10%
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39257220
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronНа моей мащине дало похти 2х кратное улутщение с 600мс на 230мс
Не повторяется у меня в два раза. Те же ~10%
Твой код чуть отличается от моего. uint вместо int и [] не используются.

У меня такие результаты
class (мс)struct (мс)struct/classС++ (мс)C++/structC++ safe (мс)C++ safe/struct4000000262181%1676%21100%4000000033329187%24584%28899%4000000006539620395%549789%596596%
C++ это без проверок выхода за пределы массива, C++ safe с проверками
C++ safe ближе к реальному коду, тут и 10% не выжать.
Исходник С++
Код: plaintext
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>

class BoolArray32 {
	int* values;
	int mask0[32], mask1[32];
	int size;

public:

	BoolArray32(int _size)
	{
		size = _size;
		values = (int*) calloc((_size - 1) / 32 + 1, sizeof(int));

		for (int i = 0; i < 32; i++)
		{
			mask1[i] = (1 << i);
			mask0[i] = ~mask1[i];
		}
	}

	~BoolArray32() {
		free(values);
	}

	bool Get(int _index)
	{
		return (values[_index >> 5] & mask1[_index & 31]);
	}

	bool GetSafe(int _index)
	{
		if (_index < 0 || _index >= size) {
			return false;
		} else {
			return (values[_index >> 5] & mask1[_index & 31]);
		}
	}

	void Set(int _index, bool _value)
	{
		if (_value)
			values[_index >> 5] |= mask1[_index & 31];
		else
			values[_index >> 5] &= mask0[_index & 31];
	}

	void SetSafe(int _index, bool _value)
	{
		if (_index >= 0 && _index < size) {
			if (_value)
				values[_index >> 5] |= mask1[_index & 31];
			else
				values[_index >> 5] &= mask0[_index & 31];
		}
	}
};

int64_t Eratosfen(int len) {
	printf("Test     %d\t" , len);
	clock_t t = clock();
	int64_t sum = 0;
	BoolArray32 s(len);
	s.Set(0, true);
	s.Set(1, true);
	int found = 0;
	while (found < len) {
		sum ^= found;
		while (found < len && s.Get(found)) found++; // Следующее простое
		for (int i = found; i < len; i += found) s.Set(i, true);
	}
	printf(" result %lld \tTime %d ms\n", sum, clock() - t);
	return sum;
}

int64_t EratosfenSafe(int len) {
	printf("Test safe %d\t", len);
	clock_t t = clock();
	int64_t sum = 0;
	BoolArray32 s(len);
	s.SetSafe(0, true);
	s.SetSafe(1, true);
	int found = 0;
	while (found < len) {
		sum ^= found;
		while (found < len && s.GetSafe(found)) found++; // Следующее простое
		for (int i = found; i < len; i += found) s.SetSafe(i, true);
	}
	printf(" result %lld \tTime %d ms\n", sum, clock() - t);
	return sum;
}

int main(int argc, char**argv)
{
	Eratosfen(4000000);
	Eratosfen(40000000);
	Eratosfen(400000000);
	EratosfenSafe(4000000);
	EratosfenSafe(40000000);
	EratosfenSafe(400000000);
	return 0;
}

...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39257294
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Safe сомнительный - исключение кидать нужно, а не подавлять ошибку
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39257375
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima T,

Safe сомнительный - исключение кидать нужно, а не подавлять ошибку
Согласен отчасти. Я же честно написал "C++ safe ближе к реальному коду". Исключений тут точно не надо, иначе С++ проиграет C# по времени, а городить огород с кодами ошибок - испоганить весь пример.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39257385
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИсключений тут точно не надо, иначе С++ проиграет C# по времени
не проиграет. как и в c# при нормальном исполнении наличие обработчиков никак не сказывается на производительности
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39257389
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TИсключений тут точно не надо, иначе С++ проиграет C# по времени
не проиграет. как и в c# при нормальном исполнении наличие обработчиков никак не сказывается на производительности
Проиграет, я попробовал. Лень табличку рисовать. Я тупо вставил else throw "error" и стало медленнее.
Я не любитель исключений, для меня С++ это "С с классами". Исключения это удобно, но как все удобное - непрактично. Даже в книгах по C# рекомендуют не злоупотреблять там где этого не надо.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39257403
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
говнокод с проверкой результата в каждой строке и последующим разборов кода возврата и отсутствием ясного диагностического сообщения и сопутствующей информации - конечно практичнее
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457552
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак показали тесты выше - портированием на С/С++ большого прироста не получишь. 5-15% максимум. Но напишешься вдоволь, т.к. там разных граблей намного больше чем в C#.

Тут решил вернуться к прошлому лету :) , а то новое что-то очень не торопится наступить, и вместо многопоточности на C# изобразить всё то же самое в 1 потоке в приложениьице командной строки, но на C/C++.
Внимание:
Результат практически вдвое хуже , чем на C# в 1 потоке !
Как такое вообще возможно??
Содержательная часть кода идентична .
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457563
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поясню немного.
Содержательная часть кода - цикл, на который тратится почти всё время работы.
Идентична - значит может быть скопирована из одного места и вставлена в другое (из C# в C++ и/или наоборот).
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457631
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Результат практически вдвое хуже , чем на C# в 1 потоке !
Неплохо бы код тестов показать, прежде чем такие громкие заявления делать.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457766
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tтакие громкие заявления

Так сам удивлён, мягко говоря, наблюдаемым результатам. Поэтому и "громкость".
Повторяю: основной рабочий цикл идентичен, с точностью до пробелов слева.
И это при том, что в варианте на C# ещё делается работа по помещению найденных в цикле результатов в упакованный массив, а в тестовом примере на C есть только счётчик количества найденного (чтобы косвенно оценить правильность алгоритма).
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457779
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Повторяю: основной рабочий цикл идентичен, с точностью до пробелов слева.
Наверно поэтому и тормозит. С/С++ и C# это разные ЯП, хоть и с похожим синтаксисом. Скорее всего что-то в коде было такое что пишется одинаково, но означает не одно и тоже.
Например
Код: c#
1.
void func(string s)


С++ создаст копию s, а C# передаст ссылку. Второе намного быстрее.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457801
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TСкорее всего что-то в коде было такое что пишется одинаково, но означает не одно и тоже.
Но при этом работает одинаково!
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
    do
    {
	int lsb = reg & 1;
	reg >>= 1;
	reg ^= (-lsb) & schema;
	shiftcnt++;
    }
    while (reg != regstart && shiftcnt < mmax);


Все переменные - типа int.
Что может измениться при переносе этого фрагмента из C# в C++?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457853
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAR®Повторяю: основной рабочий цикл идентичен, с точностью до пробелов слева.
Наверно поэтому и тормозит. С/С++ и C# это разные ЯП, хоть и с похожим синтаксисом. Скорее всего что-то в коде было такое что пишется одинаково, но означает не одно и тоже.
Например
Код: c#
1.
void func(string s)


С++ создаст копию s, а C# передаст ссылку. Второе намного быстрее.
C# передаст ссылку на ссылку :)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457905
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Что может измениться при переносе этого фрагмента из C# в C++?
Тут ничего. Затестил твой цикл. С++ быстрее.
Результат:
C++C#939 мс1145 мс
Исходники
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
#include <stdio.h>
#include <time.h>

int main()
{
	int regstart = 12345, schema = 67890, mmax = 100500000, shiftcnt = 0, check = 0;
	while(shiftcnt < 1000000000) {
		int reg = regstart;
		do
		{
			int lsb = reg & 1;
			reg >>= 1;
			reg ^= (-lsb) & schema;
			shiftcnt++;
		} while (reg != regstart && shiftcnt < mmax);
		regstart++;
		check++;
	}
	printf("shiftcnt=%d  check=%d  time %d ms\n", shiftcnt, check, clock());
	return 0;
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
		static void Main(string[] args) {
			var sw = Stopwatch.StartNew();
			int regstart = 12345, schema = 67890, mmax = 100500000, shiftcnt = 0, check = 0;
			while(shiftcnt < 1000000000) {
				int reg = regstart;
				do
				{
					int lsb = reg & 1;
					reg >>= 1;
					reg ^= (-lsb) & schema;
					shiftcnt++;
				} while (reg != regstart && shiftcnt < mmax);
				regstart++;
				check++;
			}
			Console.WriteLine($"shiftcnt={shiftcnt}  check={check}  time {sw.ElapsedMilliseconds} ms");
		}



MSVC 2015 x86

Как я и подозревал - тормоз где-то в другом месте.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457907
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВC# передаст ссылку на ссылку :)
Все-равно быстрее чем память выделять и туда копию делать.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457964
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак я и подозревал - тормоз где-то в другом месте.
Если не затруднит, попробуйте заменить тело цикла на такое (и в C# и в C++) при тех же начальных значениях переменных

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
do
{
	if ((reg & 1) == 0)
		reg >>= 1;
	else
		reg = (reg >> 1) ^ schema;
	shiftcnt++;
}
while (reg != regstart && shiftcnt < mmax);



Выросло ли время? И в C# и в C++?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457973
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T AR®Что может измениться при переносе этого фрагмента из C# в C++?
Тут ничего. Затестил твой цикл. С++ быстрее.
Результат:
C++C#939 мс1145 мс
Исходники
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
#include <stdio.h>
#include <time.h>

int main()
{
	int regstart = 12345, schema = 67890, mmax = 100500000, shiftcnt = 0, check = 0;
	while(shiftcnt < 1000000000) {
		int reg = regstart;
		do
		{
			int lsb = reg & 1;
			reg >>= 1;
			reg ^= (-lsb) & schema;
			shiftcnt++;
		} while (reg != regstart && shiftcnt < mmax);
		regstart++;
		check++;
	}
	printf("shiftcnt=%d  check=%d  time %d ms\n", shiftcnt, check, clock());
	return 0;
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
		static void Main(string[] args) {
			var sw = Stopwatch.StartNew();
			int regstart = 12345, schema = 67890, mmax = 100500000, shiftcnt = 0, check = 0;
			while(shiftcnt < 1000000000) {
				int reg = regstart;
				do
				{
					int lsb = reg & 1;
					reg >>= 1;
					reg ^= (-lsb) & schema;
					shiftcnt++;
				} while (reg != regstart && shiftcnt < mmax);
				regstart++;
				check++;
			}
			Console.WriteLine($"shiftcnt={shiftcnt}  check={check}  time {sw.ElapsedMilliseconds} ms");
		}



MSVC 2015 x86

Как я и подозревал - тормоз где-то в другом месте.Тормоз C# обычно из-за проверки границ массивов. Если писать на C# unsafe с указателями, то отличий от C++ практически нет. В качестве теста рекомендую сортировку "пузырьком", реализовать три варианта: C++ , C# и C#+unsafe+указатели .
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457981
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Выросло ли время? И в C# и в C++?
ТестC++C#До замены939 мс1145 мсПосле замены890 мс1402 мс
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457991
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КТормоз C# обычно из-за проверки границ массивов. Если писать на C# unsafe с указателями, то отличий от C++ практически нет. В качестве теста рекомендую сортировку "пузырьком", реализовать три варианта: C++ , C# и C#+unsafe+указатели .
Это понятно.

Замеры начались с обратного утверждения 20501935
AR®Тут решил вернуться к прошлому лету :) , а то новое что-то очень не торопится наступить, и вместо многопоточности на C# изобразить всё то же самое в 1 потоке в приложениьице командной строки, но на C/C++.
Внимание:
Результат практически вдвое хуже , чем на C# в 1 потоке !
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39457993
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вдогонку: тут делал тест во времена своей молодости.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458000
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TАлексей КТормоз C# обычно из-за проверки границ массивов. Если писать на C# unsafe с указателями, то отличий от C++ практически нет. В качестве теста рекомендую сортировку "пузырьком", реализовать три варианта: C++ , C# и C#+unsafe+указатели .
Это понятно.

Замеры начались с обратного утверждения 20501935
AR®Тут решил вернуться к прошлому лету :) , а то новое что-то очень не торопится наступить, и вместо многопоточности на C# изобразить всё то же самое в 1 потоке в приложениьице командной строки, но на C/C++.
Внимание:
Результат практически вдвое хуже , чем на C# в 1 потоке !Да я это не в упрёк. Просто обозначил факт, который в этом обсуждении, как мне показалось, не упоминался.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458032
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAR®Выросло ли время? И в C# и в C++?
ТестC++C#До замены939 мс1145 мсПосле замены890 мс1402 мс

Очень интересно. У меня вырастает и в C# и в C++.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458063
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Очень интересно. У меня вырастает и в C# и в C++.
Компилятор С++ какой? У меня MSVC 2015 компилирую в x86. Для запуска везде дави Ctrl+F5, так без отладчика запускается.

Странно что в C# медленнее стало, возможно С++ такую конструкцию качественнее откомпилировал.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458092
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VS2010, компилирую из среды, запускаю не из среды.

Содержательно оба варианта кода делают одно и то же.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458133
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,
не знаю что там клок делает, но sw то тормазни перед Console.WriteLine
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458145
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КВдогонку: тут делал тест во времена своей молодости.
Позапускал код по ссылке. Написал safe. Результат
ЯПВремя мсС++6047unsafe C#5943safe C#5196
Вот такая интересная картина. Рихтер писал: если компилятор видит что счетчик цикла не может выйти за границы массива, то внутри проверки границ не делаются.
Исходник safe 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.
		static void TestBubble2() {
            var buf = new int[SIZE];
            for (int i = 0; i < SIZE; i++)
                buf[i] = SIZE - i;

            Console.WriteLine("Started...");
            Stopwatch sw = new Stopwatch();
            sw.Start();

			for(int i = 0; i < buf.Length; i++) {
				for(int j = 1; j < buf.Length - i; j++) {
					if(buf[j-1] > buf[j]) {
						int t = buf[j-1];
						buf[j-1] = buf[j];
						buf[j] = t;
					}
				}
			}

            int elapsed = (int)sw.Elapsed.TotalMilliseconds;

			for (int i = 1; i < buf.Length; i++) {
				if(buf[i-1] > buf[i]) {
					Console.WriteLine("ERROR");
					break;
				}
			}

            Console.WriteLine("Elapsed: " + elapsed.ToString() + " miliseconds");
		}


PS На С++ улучшить время не получилось.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458162
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВAR®,
не знаю что там клок делает, но sw то тормазни перед Console.WriteLine
clock() в виндовсе дает время с момента старта проги в мс.
sw.Stop() на замер не влияет.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458344
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TРихтер писал: если компилятор видит что счетчик цикла не может выйти за границы массива, то внутри проверки границ не делаются.Я тоже про это где-то читал, но тогда на практике у меня это не подтвердилось. Возможно с тех пор что-то поменялось.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458414
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Меня результаты удивили. Как safe C# обогнал unsafe и С++ почти на 15%! Это уже не погрешность измерения. Проц i7-6700K

Продолжил исследования, запустил тесты на других компах:
i7-3770K все три варианта дали примерно одно и тоже, разброс <1%.
i3-2310M C++ чуть вперед вырвался

exe одни и те же, в архиве вместе с исходниками.

Какие выводы сделать даже не знаю. MS затачивает компилятор под свежие процы? Интел затачивает процы под .Net? Что еще проверить?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458448
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Started C# safe...
Elapsed: 6608 miliseconds
Started C# unsafe...
Elapsed: 6560 miliseconds

C:\Users\Roman\Downloads\test>cpp
Started C++ pointer...
Elapsed: 6578 miliseconds
Started C++ array...
Elapsed: 6609 miliseconds
у меня Intel Core i7-3770 @ 3,4 GHz
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458571
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На i7-3770K у меня похожая картина. Разбег <1%, т.е. примерно одинаково.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Started C# safe...
Elapsed: 6647 miliseconds
Started C# unsafe...
Elapsed: 6649 miliseconds

Started C++ pointer...
Elapsed: 6625 miliseconds
Started C++ array...
Elapsed: 6593 miliseconds

Непонятный реультат на i7-6700K
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Started C# safe...
Elapsed:  5013  miliseconds
Started C# unsafe...
Elapsed: 5760 miliseconds

Started C++ pointer...
Elapsed: 5828 miliseconds
Started C++ array...
Elapsed: 5844 miliseconds
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458638
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Какие выводы сделать даже не знаю. MS затачивает компилятор под свежие процы? Интел затачивает процы под .Net? Что еще проверить?
Посмотри полученный машинный код. jit создает код в зависимости от имеющегося проца, С++ имеет 100500 флагов компиляции.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458681
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМеня результаты удивили. ... Какие выводы сделать даже не знаю.
Что же тогда удивительного в моих результатах с C++ из VS2010?

Dima TMS затачивает компилятор под свежие процы?
Я этого не исключаю © :).

В Ваших результатах меня удивило, что мой другой вариант тела цикла привёл на C++ к улучшению (пусть и не очень большому), а на C# - к ухудшению. У меня с ним хуже и там, и там.
Видимо, за C++ серьёзно "взялись" к выпуску VS2015.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458737
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКакие выводы сделать даже не знаю.
Выводы нижно делать правилные: Даже код для time-critical приложений можно писать на С#.
Суть в том что промежуточный байткод может быть оттранслирован в оптималный машинный код для конкретного процессора. С нативным машинным кодом такого фокуса уже не получится.

Читать
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458765
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronDima TКакие выводы сделать даже не знаю.
Выводы нижно делать правилные: Даже код для time-critical приложений можно писать на С#.
Суть в том что промежуточный байткод может быть оттранслирован в оптималный машинный код для конкретного процессора. С нативным машинным кодом такого фокуса уже не получится.

Читать Затраты на поддержку безопасного кода в .Net таки дают о себе знать. Даже если проверка границ массивов где-то и выносится на этап компиляции, то далеко не везде. Не думаю, что компиляция под конкретный процессор может компенсировать эти затраты.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458780
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikron Читать
Там мнения разделились. Так что пока вопрос открыт.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458789
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Так что пока вопрос открыт.Всё очевидно. Производительность: С++. Надёжность: C#.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458792
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для статистики: результат для i7-4770@3.40GHz:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
D:\Trash\1>cs.exe
Started C# safe...
Elapsed: 6494 miliseconds
Started C# unsafe...
Elapsed: 6568 miliseconds

D:\Trash\1>cpp.exe
Started C++ pointer...
Elapsed: 6927 miliseconds
Started C++ array...
Elapsed: 7035 miliseconds
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458810
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КВсё очевидно. Производительность: С++. Надёжность: C#.
Да не очевидно!
У меня на С++ получилось существенно медленнее.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458814
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Алексей КВсё очевидно. Производительность: С++. Надёжность: C#.
Да не очевидно!
У меня на С++ получилось существенно медленнее.Не думаю, что в этом виноват С++. :-)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458818
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныДля статистики: результат для i7-4770@3.40GHz:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
D:\Trash\1>cs.exe
Started C# safe...
Elapsed: 6494 miliseconds
Started C# unsafe...
Elapsed: 6568 miliseconds

D:\Trash\1>cpp.exe
Started C++ pointer...
Elapsed: 6927 miliseconds
Started C++ array...
Elapsed: 7035 miliseconds
Можно ещё сравнить работу под разными версиями JIT .Net Framework.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458881
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КЗатраты на поддержку безопасного кода в .Net таки дают о себе знать. Даже если проверка границ массивов где-то и выносится на этап компиляции, то далеко не везде. Не думаю, что компиляция под конкретный процессор может компенсировать эти затраты.
Согласен. Поинт в другом.
- Байткод можно оптимизировать в зависимости от конкретной нагрузки.
т.е. например проверку условий в switch можно сделать так, что частые используемые проверяются первыми.
Вызов виртуалной функции заменить на прямой вызов. И много других фокусов.
- Байткод можно в приципе так-же запустить в "опасном" режиме.
В любом случае с байт-кодом можно работать динамически.
По аналогии с базами данных: статичный код исполнения запроса vs. оптимизатор и планировшик.
И подводя обший итог ИМХО: писать статичный код на С/С++ можно уже вчерашний день.
Для меня лично пока больше всего в С# нехватает некоторых битовых операций (поиск младшего/старшего установленого/сброшеноого бита) и некоторые устарелые принцыпй в стандартной библиотеке, которые ташятся из совместимости.
Но будушее выглядит многообешаюшим.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458887
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНе думаю, что в этом виноват С++. :-)
В этой теме я приводил цикл, на который приходится почти вся работа и который буквально переносится из C++ в C# и обратно.
Ваша версия: кто виноват? :)
Моя: компилятор C++ в VS2010.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458910
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®В этой теме я приводил цикл, на который приходится почти вся работа и который буквально переносится из C++ в C# и обратно.
Ваша версия: кто виноват? :)
Моя: компилятор C++ в VS2010.
В архиве твой тест: исходники и exe. Специально откомпилировал MSVC 6 (1998 года выпуска)

i7-6700K
Код: plaintext
1.
2.
3.
Test1() C++ shiftcnt=1000000000  check=899500816  time 901 ms
Test2() C++ shiftcnt=1000000000  check=899500816  time 877 ms
Test1() C# shiftcnt=1000000000  check=899500816  time 1092 ms
Test2() C# shiftcnt=1000000000  check=899500816  time 1228 ms

i7-3770K
Код: plaintext
1.
2.
3.
Test1() C++ shiftcnt=1000000000  check=899500816  time 1046 ms
Test2() C++ shiftcnt=1000000000  check=899500816  time 1235 ms
Test1() C# shiftcnt=1000000000  check=899500816  time 1506 ms
Test2() C# shiftcnt=1000000000  check=899500816  time 1704 ms

Просто создать пустой проект "Win32 Console application", добавить туда TestARcpp.cpp и компилировать в Release. Может ты в Debug запускаешь?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458984
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TМожет ты в Debug запускаешь?
Точно нет. В Release.

Не побоялся запустить Ваши .exe (а то время сейчас не простое) :). Спасибо!

Что сказать?
C++ выиграл однозначно у C#.
Что интересно:
1)Для C++ варианты цикла дают практически одно время, разница 10 или 20 мс то в пользу первого, то второго (например, 1470 и 1450 мс).
2)Для C# Test2() однозначно дольше, хотя и совсем не так сильно, как у меня. Типично 2130 и 2230 мс.

Как дойдут руки скомпилирую у себя, сравню.

Правильно ли я понял, что Ваш вариант на C++ скомпилирован в VS98, а C# - в VS2015?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39458990
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да: i3-2120 , 3309 МГц .
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39459011
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Dima TМожет ты в Debug запускаешь?
Точно нет. В Release.
Попробуй с нуля проект создать.
Может у тебя оптимизация выключена? В свойствах проекта C/C++ => Optimization должно стоять /O2
Попробовал отключить /Od стало втрое медленнее, результат i7-6700K
Код: plaintext
1.
Test1() C++ shiftcnt=1000000000  check=899500816  time 3722 ms
Test2() C++ shiftcnt=1000000000  check=899500816  time 3034 ms

AR®Правильно ли я понял, что Ваш вариант на C++ скомпилирован в VS98, а C# - в VS2015?
Правильно.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39459037
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
All options:
/Zi /nologo /W3 /WX- /O2 /Ob2 /Oi /Ot /Oy- /GT /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /FU"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" /analyze- /errorReport:queue
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39459092
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И ещё 1 вопрос не даёт мне покоя.
Получится ли из консольного приложеньица Win32 на C++ работать с БД MS SQL Server?
И, если да, то через что? OLEDB ?
В C# я перешёл с OLEDB на System.Data.SqlClient и меня всё устраивает.
А как быть в C++ ?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39459120
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®И ещё 1 вопрос не даёт мне покоя.
Получится ли из консольного приложеньица Win32 на C++ работать с БД MS SQL Server?
Без разницы: консольное или с гуем.
AR®И, если да, то через что? OLEDB ?
В C# я перешёл с OLEDB на System.Data.SqlClient и меня всё устраивает.
А как быть в C++ ?
Понятия не имею, не работал с БД из С/С++. Вместе с MS SQL ставится SDK для С/С++. Наверно и примеры его использования есть на сайте MS.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39459775
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВместе с MS SQL ставится SDK для С/С++. Наверно и примеры его использования есть на сайте MS.

Есть только sqlncli.h / sqlncli10.lib. Примеров нет. Может в Developer Edition какой-нибудь и есть они.
Вообще, поискав урывками сегодня, понял, что найти законченный пример работы с БД MS SQL на C++ - нетривиальная задача. :))
Более-менее написано здесь , но у меня не заработало. И, как я понял, там через ODBC, а я не очень этого хочу.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39459849
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,
http://www.cyberguru.ru/programming/visual-cpp/odbc-using.html
Вообще плюсы немного для другого.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460175
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВ http://www.cyberguru.ru/programming/visual-cpp/odbc-using.html

Спасибо. Возможно, в выходные поразбираюсь.
Вообще, ценность C++ (быстродействие в целочисленной арифметике) для моих целей оказалась неподтверждённой.
А тут рассмотрел, что в System.Data.SqlClient ест аналог BCP, а значит, просматривается возможность сэкономить время не на работе, а на записи результатов в БД (порядка миллионов записей).

Всё более хочется "остаться" на C#.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460197
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,
Если нужна скорость плюсов и возможности .NET Framework, то бете сюда
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460264
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Вообще, ценность C++ (быстродействие в целочисленной арифметике) для моих целей оказалась неподтверждённой.
C# в этом не сильно проигрывает, а иногда даже выигрывает.
AR®А тут рассмотрел, что в System.Data.SqlClient ест аналог BCP, а значит, просматривается возможность сэкономить время не на работе, а на записи результатов в БД (порядка миллионов записей).
Это все обертки над BULK INSERT , который можно вызывать откуда угодно.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460297
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВAR®,Если нужна скорость плюсов

Так не получилось её, скорости, даже в unmanaged варианте. Пока не понял, почему.

Вчера вечером прочёл это это , что склонило бы весы в пользу C++, но если оно же доступно в System.Data.SqlClient , то пусть C#.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460299
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЭто все обертки над BULK INSERT
Ничего подобного. BULK INSERT импортирует файл, и только из расположения, которое видит сервер. Внутри SqlBulkCopy - обертка над
INSERT BULK , спец. синтаксиса только для внешних приложений, работающих с TDS-протоколом . Этот протокол принимает и передает на сервер потоковые данные, за счет чего и обеспечивает высокую производительность вставки (ну, и плюс минимальное журналирование). Делать самому всё вот это (включая разбирательства с quoted names, коллейшенами, маппингами колонок, контролем соответствия типов данных, итд) - проще сразу убиться. Особенно при наличии готового класса.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460307
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЭто все обертки над BULK INSERT , который можно вызывать откуда угодно.

Правильно. Весь вопрос в том, как удобно её вызвать, когда, например, есть массив из нескольких миллионов записей. Сохранить в файл, а потом звать bcp.exe? Тогда программа становится не самодостаточной, кроме того, bcp.exe - тоже не самодостаточна и хочет видеть нескольких dll из состава SQL сервера. Класть файл на сервер (а потом звать в запросе BULK INSERT) тоже далеко не всегда возможно.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460311
Фотография ЕвгенийВ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®,
Есть вопросы - заведи свою тему, а то твои вопросы не коррелируют с размером ConcurrentDictionary.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460315
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Правильно.
Неправильно.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460321
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЕвгенийВтвои вопросы не коррелируют с размером ConcurrentDictionary

Согласен, не коррелируют. Но "генетически" происходят от него в рамках решения одной задачи. Да и плодить темы не очень здорово. В конце концов, автор этой темы - я. :)
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460324
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Dima TЭто все обертки над BULK INSERT , который можно вызывать откуда угодно.

Правильно. Весь вопрос в том, как удобно её вызвать, когда, например, есть массив из нескольких миллионов записей. Сохранить в файл, а потом звать bcp.exe? Тогда программа становится не самодостаточной, кроме того, bcp.exe - тоже не самодостаточна и хочет видеть нескольких dll из состава SQL сервера. Класть файл на сервер (а потом звать в запросе BULK INSERT) тоже далеко не всегда возможно.
bcp.exe просто посылает команду BULK INSERT, можешь сам ее послать через ADO.NET
Код: c#
1.
2.
			var query = new SqlCommand("BULK INSERT ...", db);
			query.ExecuteNonQuery();


Если положить файл на сервер проблема, то с INSERT BULK поразбирайся 20514170

Но тут видится совсем другая проблема: надо ли эти миллионы записей загонять в БД? Может достаточно сохранить в файл?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39460595
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tнадо ли эти миллионы записей загонять в БД? Может достаточно сохранить в файл?
Надо :)
Для использования другим пользователями БД.
Вести с полей такие:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
                    try
                    {
                        bulkCopy.WriteToServer(rows); // Write from the source to the destination.
                    }
                    catch
                    {
                        MessageBox.Show("Ошибка BCP при сохранении результатов в БД");
                    }


упало на 8 млн записей, хотя на маленьких кол-вах работает "на ура".
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462807
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кmikronпропущено...

Выводы нижно делать правилные: Даже код для time-critical приложений можно писать на С#.
Суть в том что промежуточный байткод может быть оттранслирован в оптималный машинный код для конкретного процессора. С нативным машинным кодом такого фокуса уже не получится.

Читать Затраты на поддержку безопасного кода в .Net таки дают о себе знать. Даже если проверка границ массивов где-то и выносится на этап компиляции, то далеко не везде. Не думаю, что компиляция под конкретный процессор может компенсировать эти затраты.
не надо путать холодное с мягким

компиляцию под конкретную платформу можно использовать и для С кода, например используя байт-код LLVM или напрямую указывая компилятору оптимизацию под определённую платформу

автосборку мусора и проверку выходов за границу массивов можно сделать и в нативном языке

это совершенно не связанные вещи
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462820
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Вести с полей такие:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
                    try
                    {
                        bulkCopy.WriteToServer(rows); // Write from the source to the destination.
                    }
                    catch
                    {
                        MessageBox.Show("Ошибка BCP при сохранении результатов в БД");
                    }


упало на 8 млн записей, хотя на маленьких кол-вах работает "на ура".
Как именно упало? Сказало "нихачу больше работать", и закрылось?
P.S. для миллионных объемов записей есть перегрузки SqlBulkCopy.WriteToServer, принимающие на вход DbDataReader/IDbDataReader. Чтобы не закачивать предварительно все эти миллионы записей на клиента, а отдавать на запись по мере получения.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462892
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)Алексей Кпропущено...
Затраты на поддержку безопасного кода в .Net таки дают о себе знать. Даже если проверка границ массивов где-то и выносится на этап компиляции, то далеко не везде. Не думаю, что компиляция под конкретный процессор может компенсировать эти затраты.
не надо путать холодное с мягким

компиляцию под конкретную платформу можно использовать и для С кода, например используя байт-код LLVM или напрямую указывая компилятору оптимизацию под определённую платформу

автосборку мусора и проверку выходов за границу массивов можно сделать и в нативном языке

это совершенно не связанные вещи

Хороший пример LLVM, показывает преимущества промежуточного byte-code. Сегодня x86 завтра ARM и везде оптимально выполняется в рамках платформы/ОС. Таким образом MSIL не является чем то ограничивающим.
Проверки границ массивов: Да, они стоят время. Но теоретически, что мешает их полностью уничтожит во времена выполнения? майкрософт надеюсь (скоро) поймёт что встраивать меры защиты в среду выполнения - напрасная затея: только вредит распространению платформы и не увеличивает безопасность системы. ИМХО Безопасность системы должна и может гарантировать только сама система. Тогда можно ожидать и появления необходимых ключей/switches для JIT и сравнимую производительность.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462906
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronПроверки границ массивов: Да, они стоят время. Но теоретически, что мешает их полностью уничтожит во времена выполнения?
Кое-какие шаги МС сделал в этом направлении 20504475
Полностью не уничтожить, например если индекс как-то рассчитывается, то контроль нужен.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462927
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПолностью не уничтожить, например если индекс как-то рассчитывается, то контроль нужен.
Почему нужен?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462969
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныКак именно упало? Сказало "нихачу больше работать", и закрылось?

Примерно так. :) Текст сообщения приведён в коде выше. Из-за нехватки времени не анализировал exception.
Использовал перегрузки SqlBulkCopy.WriteToServer(DataTable) и SqlBulkCopy.WriteToServer(DataRow[]) - результаты близки. 6 млн. записей проходит, пришлось писать разбивку на куски.

Сон Веры ПавловныЧтобы не закачивать предварительно все эти миллионы записей на клиента, а отдавать на запись по мере получения.
Они у меня образуются на клиенте, ничего закачивать не надо.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39462977
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Они у меня образуются на клиенте, ничего закачивать не надо.
Имплементируйте свой IDataReader, и отдавайте по мере образования, и будет вам щастье.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463007
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныИмплементируйте свой IDataReader, и отдавайте по мере образования, и будет вам щастье.
Чем это будет лучше использования запроса в стиле IF NOT EXIST... INSERT... VALUES... ?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463045
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR® в стиле IF NOT EXIST... INSERT... VALUES... ?
С этого места поподробней:
Сколько записей в таблице? сколько реально вставляется из 8 млн.?

Как вариант: можно IF NOT EXIST проверять до отправки в БД, т.е. залить таблицу в Dictionary и там проверять, если нет, то INSERT.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463128
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronDima TПолностью не уничтожить, например если индекс как-то рассчитывается, то контроль нужен.
Почему нужен?
Я собственно про вот это
JitSkipArrayBoundCheck
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463142
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAR® в стиле IF NOT EXIST... INSERT... VALUES... ?
С этого места поподробней: Сколько записей в таблице? сколько реально вставляется из 8 млн.?


Сейчас 49 млн.
Текущий этап работы даст ещё ~69 млн.(из которых было сделано 8 на момент начала экспериментов с SqlBulkCopy.WriteToServer() )
Так говорит наука математика. :)
До открытия мной (разумеется, для себя) SqlBulkCopy в .Net я рисовал IF NOT EXISTS... INSERT... VALUES... по ~тысяче записей за батч и запускал на выполнение.
Теперь просто придётся перед нажатием кнопки сохранения проверить, что не будет нарушения PK таблицы.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463143
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronmikronпропущено...

Почему нужен?
Я собственно про вот это
JitSkipArrayBoundCheck
Не понял о чем там речь.
Я вот о чем: адрес элемента массива вычисляется по формуле
Код: c#
1.
адрес первого элемента + i * K


где i индекс нужного элемента, K размер элемента в байтах.

Если вдруг i окажется больше размера массива, то произойдет обращение непонятно куда, а т.к. адресное пространство линейно, то там может оказаться содержимое другого объекта. Если туда что-нибудь записать, то кривой код отработает без ошибок, а когда дойдет до использования испорченного объекта, то начнется мистика и косяк искать будет очень тяжело. ИМХО от этого никак не защититься, кроме как предварительной проверкой индекса.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463155
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, 2 копейки про надёжность C#, а точнее - про разочарование в ней.
Код: c#
1.
for (int i = Min; i <= Max; i++)	


Что произойдёт, если Max == 2147483647 == Int32.MaxValue ?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463188
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tmikronпропущено...

Я собственно про вот это
JitSkipArrayBoundCheck
Не понял о чем там речь.
Я вот о чем: адрес элемента массива вычисляется по формуле
Код: c#
1.
адрес первого элемента + i * K


где i индекс нужного элемента, K размер элемента в байтах.

Если вдруг i окажется больше размера массива, то произойдет обращение непонятно куда, а т.к. адресное пространство линейно, то там может оказаться содержимое другого объекта. Если туда что-нибудь записать, то кривой код отработает без ошибок, а когда дойдет до использования испорченного объекта, то начнется мистика и косяк искать будет очень тяжело. ИМХО от этого никак не защититься, кроме как предварительной проверкой индекса.
Это вроде как общеизвестно.
Я о чем: мы сравниваем скорость MSIL с native code. Много факторов влияет на результат сравнения,
но два фундаментальных для .Net CLR: JIT и Boundary checks.
JIT - иногда сильно помогает, редко - ограничивает (oсобенно заметно для короткоживущих приложений), но не для приведённых тестов.
Boundary checks - ограничивают и влияют на приведенные тесты, но могут быть удалены/выключены для CLR. Ссылку я привел. Вот если их выключит то можно сравнивать native code vs. MSIL на более равных условиях.
Твоё утверждение, что их (boundary checks) нельзя убрать и контроль границ нужен я не понял. Почему ты так считаеш?
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463191
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®Кстати, 2 копейки про надёжность C#, а точнее - про разочарование в ней.
Код: c#
1.
for (int i = Min; i <= Max; i++)	


Что произойдёт, если Max == 2147483647 == Int32.MaxValue ?

А так?
Код: c#
1.
2.
3.
checked {
for (int i = Min; i <= Max; i++)	
}
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463217
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronА так?
Можно и так, но на все циклы checked'ов не напасёшься.
Получилось неприятно, т.к. цикл был долгий сам по себе, и было не очевидно, что произошло зацикливание.

Да и брать в checked{}, получается, надо всё тело цикла, а в нём много всего, что проверять не требуется. В результате опять будет не лучшее время.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463225
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AR®mikronА так?
Можно и так, но на все циклы checked'ов не напасёшься.
Получилось неприятно, т.к. цикл был долгий сам по себе, и было не очевидно, что произошло зацикливание.

Да и брать в checked{}, получается, надо всё тело цикла, а в нём много всего, что проверять не требуется. В результате опять будет не лучшее время.

Да просто лень, да?
Код: c#
1.
for (int i = Min; i <= Max; i = checked(i+1))
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463227
AR®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уже сам догадался. :)
Так, пожалуй, можно.
...
Рейтинг: 0 / 0
Максимальный размер ConcurrentDictionary в 32-битных приложениях
    #39463228
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronТвоё утверждение, что их (boundary checks) нельзя убрать и контроль границ нужен я не понял. Почему ты так считаеш?
Мое утверждение было немного о другом 20504475
Я к тому что там где можно убрать - компилятор C# сам убирает и не надо извращаться с unsafe, все уже оптимизировано, результаты того теста это подтверждают. Но есть случаи когда индекс элемента не счетчик цикла, а вычисляемое значение или полученное извне, тут его надо проверять хоть в C# хоть в С++, иначе можно получить вышеописанную проблему.
...
Рейтинг: 0 / 0
196 сообщений из 196, показаны все 8 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Максимальный размер ConcurrentDictionary в 32-битных приложениях
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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