|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
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 байта. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2016, 16:00 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®выяснил, что, например, BitArray даёт время работы раза ~в 4 больше, чем bool[ ] (он используется у меня в каждом отдельном потоке). Можно немного пооптимизировать. Заменить Код: c# 1.
на массив Код: c# 1.
заполнить его один раз и использовать Код: c# 1.
В С/С++ это дает ускорение, в C# не знаю, т.к. будет еще доп.проверка на выход за границу массива. Тоже мерить надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.05.2016, 16:13 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Вести с полей. Таблица ниже содержит времена работы одного и того же алгоритма (чч:мм:сс.мс), в котором для массивов значений 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. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2016, 17:27 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Некоторые выводы. 1. Самописные классы существенно эффективнее BitArray 2. Использование для упаковки short приблизительно в полтора раза хуже использования byte, а long - ещё хуже (на 32-битной ОС) 3. Использование byte приблизительно равнозначно использованию int. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2016, 17:38 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Почти совпало с моими предсказаниями 19228795 . Странный результат с short, проверь что в коде BoolArray16 ничего не напутано. long надо на x64 тестить. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2016, 18:15 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Класс 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 11:09 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®, что то меня берут сомнения у вас на 20 bool[] -00:11:28.826; BoolArray16 -00:15:42.784 у меня 5 миллисекунд и 20 соответственно обыкновенный цикл заполнения и считывания? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 13:09 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®Класс BoolArray16:... Выглядит нормально. Значит в .net что-то недооптимизировано с short Где-то в степи что то меня берут сомнения у вас на 20 Не 20 а 2^20, и, как понял, гонял он какой-то свой алгоритм чего-то считающий с интенсивным использованием массива bool[]. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 13:32 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Dima T, я и написал на 20( читать 2^20) какой может быть алгоритм доступа к массиву?,BoolArray16 - это я вижу а где код замеров, обычно когда выкладываю таблицу замеров - принято и выкладывать весь механизм замера, тем более выводить по ним резюме... ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 13:46 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Выкладывать весь алгоритм и его цель я не буду, но суть опишу. В нескольких параллельно работающих потоках (приблизительно равноправных по объёму работы) создаются массивы значений bool указанного размера. По ходу решения задачи они многократно заполняются по определённой логике и по окончании шага цикла очищаются. Механизм замера - вызов DateTime.Now в начале работы и DateTime.Subtract() в конце. Есть, конечно, погрешность, связанная с непостоянной текущей загруженностью компа во время работы. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 14:00 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
И ещё. Если дорисовать в классе public bool this[int index] и обращаться как к элементам массива, то работа замедляется приблизительно на 3%, что для меня не мало. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 14:05 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Где-то в степиDima T, я и написал на 20( читать 2^20) какой может быть алгоритм доступа к массиву?,BoolArray16 - это я вижу а где код замеров, обычно когда выкладываю таблицу замеров - принято и выкладывать весь механизм замера, тем более выводить по ним резюме... ИМХУ твой тест не показательный. Он очень быстро происходит, а разницу в 10 мс можно просто списать на погрешность измерения. Да и линейный он, что тоже редко встречается в реальной жизни. Если уж полноценное тестирование устраивать, то надо какой-нибудь долгоиграющий несложный алгоритм, который непоследовательно будет обращаться к разным элементам. Например посчитать количество/сумму всех простых чисел до N Решетом Эратосфена . А так в целом результаты AR® достаточно показательны, если он менял только тип массива. Правда немного смущает что многопоточно работало. PS Как подозреваю bool[] становится медленнее когда перестает влазить в кэш проца. Битовый массив в 8 раз меньше памяти занимает. Если так, то тут играет роль не только размер массива, но и остального что в это время используется. Т.е. для разных алгоритмов этот "пограничный" размер будет разный. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 14:17 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Dima T Правда немного смущает что многопоточно работало. Подчеркну, что здесь речь про массивы, используемые каждый в своём потоке, к ним нет конкурентного доступа. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 14:25 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Dima T, ну давай возьмем,^30 массив 11 секунд костыль 23 секунды замерял наручными часами, или есть желание через песочные? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 14:36 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Где-то в степи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.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 15:39 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®Dima T Правда немного смущает что многопоточно работало. Подчеркну, что здесь речь про массивы, используемые каждый в своём потоке, к ним нет конкурентного доступа. Я о другом. Допустим есть 4 потока, запускаются одновременно, ты меришь по последнему, предположим в одном случае последним заканчивает например 1-й, в другом 3-й. В итоге получается ерунда: замеры двух разных расчетов (на разных исходных данных). Другой момент - включен гипертрейдинг на проце, например два потока могу оказаться на одном реальном ядре, а могут на двух разных. Тут тоже заметная разница будет. 2-хядерный проц с HT (виндовс показывает как 4 ядра) реально работает с производительностью максимум ~2,5 ядра, т.е. 4 потока в 2,5 раза быстрее чем 1, но 2 потока в 2 раза быстрее. (при условии что синхронизация не требуется) Не утверждаю что у тебя что-то из описанного было, я к тому что для чистоты эксперимента замеры лучше делать однопоточно. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 16:41 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Я делал столько потоков, сколько возвращает Environment.ProcessorCount. У меня это 4. По ходу экспериментов выяснилось, что диспетчер задач показывает загрузку прямо пропорционально количеству "вычислительных" потоков (если их <=4), т.е. для 1 потока - 25%, 2 - 50 %, 3 - 75 %, 4 - 99%. Т.е. можно считать, что каждый поток всё-таки оказывается в отдельном ядре. И ещё интересно, что диспетчер задач показывает для моей программы общее число потоков 9. При 4 запущенных мной явно это означает, что в 5 потоках "живёт" единственное окно с полями и кнопкой? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 16:57 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
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 потоках "живёт" единственное окно с полями и кнопкой? Это пул потоков заранее создал запасные, на случай если что-то асинхронно надо будет выполнять. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 17:15 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
На моём компе до размера массивов 2^17 наблюдалось довольно чёткое учетверение при переходе от 1 потока к 4. При 2^18 и 2^19 - ближе к утроению, дальше - ближе к удвоению. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 17:25 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®На моём компе до размера массивов 2^17 наблюдалось довольно чёткое учетверение при переходе от 1 потока к 4. При 2^18 и 2^19 - ближе к утроению, дальше - ближе к удвоению. Проц какой? Сколько реальных ядер? Тут еще такой момент есть: расчет должен быть поделен между потоками равномерно. Может оказаться что стартуют все 4 одновременно, но один работает секунду, второй - две, третий - 3, 4-й - четыре. В итоге общее время 10 секунд, но отработало за 4 (максимальное), хотя в идеале должно быть 2,5 (10/4). Ну и Закон Амдала мешает если есть хоть мало-мальская синхронизация. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2016, 18:22 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Intel Core i3-2120 @ 3,3 ГГц. Диспетчер устройств показывает четыре процессора, а сколько реальных ядер, я не знаю. Работа разделена между потоками достаточно поровну, а синхронизации между потоками нет за ненадобностью. Есть "взаимопомощь" между потоками, когда побочный результат работы одного потока снимает часть работы с другого, что и вынудило копать в сторону ConcurrentDictionary. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2016, 09:39 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®сколько реальных ядер, я не знаю. http://ark.intel.com/ru/products/53426/Intel-Core-i3-2120-Processor-3M-Cache-3_30-GHz ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2016, 09:59 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
AR®Intel Core i3-2120 @ 3,3 ГГц. Диспетчер устройств показывает четыре процессора, а сколько реальных ядер, я не знаю. На сайте интела все написано Intel Core i3-2120 . Реальных 2 ядра у тебя. На расчетных задачах максимум ускорения в 2,5 раза, при полной загрузке всех логических процов на 100% AR®Работа разделена между потоками достаточно поровну, а синхронизации между потоками нет за ненадобностью. Есть "взаимопомощь" между потоками, когда побочный результат работы одного потока снимает часть работы с другого, что и вынудило копать в сторону ConcurrentDictionary. Если есть какие-то промежуточные результаты необходимые разным потокам, то может есть смысл сами результаты кэшировать. Т.е. досчитал до места, которое возможно уже посчитано, заглянул в кэш, если есть - взял, если нет - посчитал, записал в кэш. Кэш делать тем же ConcurrentDictionary, а внутри как есть оставить. Тут алгоритм надо смотреть, что кэшировать и сколько места под кэш надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2016, 09:59 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
Dima TЕсли есть какие-то промежуточные результаты необходимые разным потокам, то может есть смысл сами результаты кэшировать. Т.е. досчитал до места, которое возможно уже посчитано, заглянул в кэш, если есть - взял, если нет - посчитал, записал в кэш. Кэш делать тем же ConcurrentDictionary, а внутри как есть оставить. Именно так всё и сделано с самого начала. Только с ростом размера данных пришлось отказаться от ConcurrentDictionary в пользу BitArray и lock{}. Попутно поделюсь ещё одним открытием, про которое не знают даже в MS :) Замена кода Код: c# 1. 2.
на Код: c# 1. 2.
в моём BoolArray32 не приводит ни к чему, а аналогичная в BoolArray8, BoolArray16 - к потере скорости на 15-20 % ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2016, 10:43 |
|
Максимальный размер ConcurrentDictionary в 32-битных приложениях
|
|||
---|---|---|---|
#18+
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.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2016, 15:47 |
|
|
start [/forum/topic.php?fid=20&msg=39247454&tid=1399876]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
30ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 282ms |
total: | 408ms |
0 / 0 |