Re[12]: Горутины и потоки
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.07.21 07:29
Оценка:
Здравствуйте, Serginio1, Вы писали:

N>>>>Эээ... после выполнения захвата лока (речь об этом, да?) как раз лучше не отдавать управление, а сделать максимум действий во время захвата. А до него — если лок занят — то раз ждём, надо оповестить шедулер о том, что есть отличный повод запустить другую задачу.

S>>> Я как раз про то, что если lock короткий, то не стоит передавать управление на другой поток.

N>>Так передавать когда? До него или после? В случае удачного захвата или неудачного?

S>При удачном захвате стоит дождаться освобождения, что бы другие потоки могли воспользоваться свободным монитором

Вероятность прерывания в этот момент для интерактивной нитки (который больше спит и реагирует на события, чем ест процессор) крайне мала (при сколь-нибудь умном шедулере, разумеется).

Более того, в случае await-based построения работы вероятность насильственного переключения со стороны ОС выше, если нет возможности её явно проинструктировать "тут воздержись, а тут больше свободы" — если гружёный процесс держит всю активность в нескольких нитках по количеству хартов — с точки зрения ОС это одна неуправляемая прожора, и когда переключать на соседей — она просто не в курсе.

N>>Да, проблема есть (хотя про "основной источник проблем с производительностью" тут загнули, случай он разный бывает). Но вы никак от этого не избавитесь ни шедулингом, ни переходом на await, пока вам потребуется ровно та же синхронизация.

S> Я тебе привел пример аналога LockAsync. Поток ничего не ждет, а по событию запускается из пула потоков. Вот пример асинхронной очереди
S>AsyncProducerConsumerCollection
S>Просто привел пример с использованием ValueTask вместо Task

Так с точки зрения ОС что поможет тут осознать, когда можно переключать на другую нить вообще другого процесса, а когда лучше этого не делать, потому что захвачен важный лок (и даже в случае асинхронных локов это блокирует другие задачи)?
Я б ожидал каких-то явных системных вызовов, но тут про них ни слова.

N>>Если так, то та же цена реально размазана по остальной работе: с данными в куче всегда дороже работать, чем с данными на стеке или тем более в регистрах: аллокация, GC где-то после, разыменование указателей (спрятанных в ссылках дотнетов), заметно худшее кэширование, потому что в стеке данные сидят плотно, и наверняка ещё и пара сотен байт вершины стека в кэшах процессора.

S> Угу который при переходе на новый поток сбрасывается.

Кто сбрасывается? Кэш процессора? Зачем? Даже с мерами против Meltdown/Spectre кэш сбрасывается при переключении между процессами, а не между нитками одного процесса. Хотя о чём и, главное, чем думают тут в MS, я не в курсе.

S>У меня вопрос если все так прекрасно с переключением потоков, то зачем делают все, что бы отказаться от потоков и использовать очередь потоков?


Кто сказал, что "всё прекрасно"? Я не знаю, откуда и как вы делаете такие выводы.
И что это "все", что делают чтобы отказаться? В основном делают там, где просто неудобно/дорого по другим причинам возлагать это на ОС.

Да, есть цена на переключение, даже вход и выход из системного вызова чего-то стоит, и на Windows эта цена сильно выше, чем на Linux. Может, потому для Windows и стараются сократить эти переключения. В Linux я не вижу такого активного стремления, если где-то такое делают, то в рантаймах со сложной собственной логикой и полностью "управляемым" выполнением (Go, Erlang).

N>>Не может быть квадратных кругов и круглых квадратов. Если с данными надо работать, то для этого нужен доступ к ним. Если нужен доступ, их надо прочитать из памяти и записать в память, с соответствующей ценой. Я бы предпочёл, чтобы компиляция хранила максимум в регистрах процессора, а что не помещается — максимум на стеке: не будет дурных потерь скорости. А если при этом само переключение формально дороже — тоже не страшно, записать компактно пару сотен байт и потом прочитать — эффективнее, чем размазывать их по десяткам кэш-строк.


S>Ну класс если используешь Value типы тоже будут компактно расположены, а не валуе типы что на стеке, что не на нем все равно в куче


То есть в дотнет ещё не завезли escape analysis? (сомневаюсь)

S>>>>>Конечно зависит от длительности задач, но если задачи непродолжительные, то пул потоков может и не переключаться а выполнять очередь заданий.

N>>>>Тоже не понимаю, при чём тут эта реплика.
S>>> В том, что с использованием пула потоков сводит к минимуму переключение потоков

N>>Так не от желания конкретной задачи тут зависит, а от того, будет ли тот лок свободен.

S>Вот ссылочка из предыдущего сообщения AsyncSemaphore

S>Если lock занят то возвращается Task и ожидается пока не вызовется SetResult

S>Никакой остановки потока нет. Да внутри конечно есть короткий lock который нужно заменять на SpinLock

Почему это "нужно заменять"? Обычный lock настолько неэффективен?
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.