Здравствуйте, ·, Вы писали:
·>Здравствуйте, Serginio1, Вы писали:
S>>>> За счет того, что состояние хранит не на стеке потока, и в регистрах, а в полях класса. А те которые в потоке с ними проще работать, так как в пуле их немного.
S>>·>Какое ты увидел состояние в том коде? В каких полях какого класса?
S>> А поток, что выполняет? В Task создается класс и автомат для перехода по await
·>В потоке эмулируется конкурентный доступ к общему кешу.
Да только в реальной жизни это делается из пула потоков. Обычная практика для ASP.Net
И таких жутких историй нет.
Но в свое время была проблема, когда изменялись данные, которые находились в старших поколениях, для них GC делал движения, для того, что бы учесть эти изменения.
И соответственно огромные тормоза при изменении огромного количества ссылок.
http://rsdn.org/forum/dotnet/415352.1Автор: Serginio1
Дата: 20.10.03
Это нужно учитывать. Посмотри на дату. Сейчас может все по другому.
Кстати по алгоритму то и получается, что кэш
var bytes = new byte[80 * 1024];
random.NextBytes(bytes);
bytesCache.Set(bytes.GetHashCode(), bytes);
bytesCache будет постоянно обновляться. Поэтому если bytesCache будет постоянно в 0 поколении, то и задержки будут постоянными
S>>·>Эээ... И что? Я всё ещё не понимаю как это относится к тому коду, к особенностям работы gc и к LL?
S>> Это относится к тому, что потоки это уже старое ненужное.
·>Ой-ё.
Да-да
S>>>> Кстати ветка по поводу асинхронного программирования. Как оптимизировать выполнения 10000 параллельных задач?
S>>·>В случае LL выполнение 10000 параллельных задач не бывает. Не надо путать low latency и high throughput.
S>> Ты привел какой то непонятный пример с огромным количеством потоков. На GC как раз влияет количество потоков, где нужно его останавливать, смотреть стек потока регистры.
·>К сожалению конкретных цифр я не смог найти, но в тексте написано "several threads", на случай если ты не знаешь английский переведу: "несколько потоков". Про "огромное количество потоков" ты придумал сам, с собой и спорь.
Ну я же привел те
·>Несколько потоков это обычно для LL-применений: разные треды делают вполне конкретную и довольно разную работу: читают данные из сетевого буфера, делают какие-то вычисления, реплицируют, пишут на диск, пишут в сеть и т.п. Таких тредов как правило меньше чем ядер процессора.
Что прекрасно походит под async await.
·>10к потоков характерно для high throughput задач, когда один сервер с жалкой сотней ядер тужится эффективно обработать миллионы однотипных запросов, в таких случаях редкие зависоны на 1-2 секунды никто не замечает, в LL мире такой зависон является critical production issue и в лучшем случае персональные извинения перед клиентом.
S>>В Task все данные хранятся внутри генерируемого класса. Async/await и механизм реализации в C# 5.0
S>>https://habrahabr.ru/post/260217/
S>> При этом пока задача вне потока выполнения код хранится в виде делегата. Никакого стека, регистров. Нужно приостановить только планировщик.
·>А делегат где хранится?
В обычной или асинхронной очереди.
·>Ты видимо вообще не понимаешь что такое LL. Там ничего приостанавливать нельзя.
А как ты будешь собирать мусор? Для этого нужно знать граф доступных объектов, которые кстати хранятся в стеке и регистрах.
А все, что ты описываешь, это обычный async await. И ни у кого таких историй про задержки GC 2 секунды я не слышал.
А сколько в итоге то Объектов то хранится в bytesCache.
Количество строк ограничено алфавитом, и все символы повторяются 1000 раз
processingThreads[i] = new Thread(() =>
{
var threadCounter = 0;
while (true)
{
var text = new string((char)random.Next(start, end + 1), 1000);
stringCache.Set(text.GetHashCode(), text);
// Use 80K, If we are > 85,000 bytes = LOH and we don't want these there
var bytes = new byte[80 * 1024];
random.NextBytes(bytes);
bytesCache.Set(bytes.GetHashCode(), bytes);
threadCounter++;
Thread.Sleep(1); // So we don't thrash the CPU!!!!
}
});
Или всю память заполнили, а потом начинаем бороться с GC?