Наше приложение сильно загружено процессором, чтобы максимально быстро обрабатывать миллиарды кортежей данных. Он использует многоядерные процессоры и вскоре перейдет к распределению в облаке.
Таким образом, цель состоит в том, чтобы максимально эффективно использовать процессор. Этот вопрос о том, как поддерживать высокий уровень производительности, позволяющий динамически загружать / выгружать заглушки во время выполнения.
Пожалуйста, поймите, что хотя обмен данными между доменами приложений прост, ни один из "простых" способов не будет соответствовать приведенным выше требованиям к производительности. Таким образом, в этом вопросе обсуждаются причины, по которым обычные методы являются слишком медленными, и дополнительные требования, а также конкретные вопросы наших идей, которые необходимо решить.
Для достижения производительности приложение было разработано для обмена данными между компонентами с помощью «передачи сообщений», что означает, что у нас есть планировщик задач в пользовательском режиме, чтобы эти потоки были заняты без какой-либо (кроме случаев, когда это необходимо) отмены любых временных интервалов или контекста. переключается на операционную систему.
ЕДИНСТВЕННЫЙ способ выгрузки DLL в .NET - через домены приложений. Тем не менее, для поддержания высокого уровня производительности, описанного выше, это означает, что пул потоков (у нас есть собственный пул потоков), должен иметь возможность выполнять задачи в различных доменах приложений.
В частности, будет ужасно иметь отдельные потоки для каждого из десятков доменов приложений, которые затем конкурируют за ЦП. Большее количество потоков, чем ядер, для работы с привязкой к ЦП снизит производительность, поскольку операционные системы тратят огромное время на переключение контекста между потоками.
Похоже, что после предварительного исследования наш эффективный пул потоков может перейти в другой домен приложений с любой приличной производительностью. Удаленное взаимодействие или сериализация невозможны даже при отсутствии аргументов методов.
Обратите внимание, что речь идет не об обмене данными. Мы не хотим использовать потоковые вызовы в разные домены приложений для передачи данных. Вместо этого мы рассчитываем обмениваться данными между доменами приложений через сокеты и файлы с отображением в памяти для обеспечения максимальной летной производительности, как и при надлежащем межпроцессном взаимодействии. Так что этот вопрос относится только к тому, чтобы потоки работали в доменах приложений.
Следующая ссылка здесь на Stackoverflow, которой более 2 лет, намекает на использование встроенного пула потоков в CLR для .Net, в котором говорится, что он пересекает другие домены приложений для выполнения задач. Документация MS также подтверждает, что пул потоков CLR работает во всех доменах приложений.
.Net Как создать собственный поток ThreadPool, общий для всех доменов приложения процесса?
Тем не менее после прочтения документации, как использовать встроенный пул потоков в AppDomain, НИКОГДА не разрешая переключение контекста при пересечении доменов?
Таким образом, цель проекта заключается в том, чтобы вращать потоки (по одному на ядро), чтобы часто проверять «очередь выполнения» задач в каждом домене приложений, чтобы увидеть, есть ли там работа, а затем перейти к следующему домену приложений? И так далее, проходя через каждый планировщик AppDomains? Как сделать это без ожидания каких-либо переключений контекста или удаленного взаимодействия или маршалинга?
Обратите внимание, что, конечно, у нас есть некоторый ум, в котором домены приложений назначаются каждому потоку, чтобы избежать пропусков кэша L1 и, таким образом, избежать аппаратных узких мест.
Также еще одна идея, которая нас интересует, - это написать наш собственный хост CLR. Похоже, что C ++ API позволяет реализовать наш собственный пул потоков. Кто-нибудь знает, если это позволит вышеуказанные возможности? Если так, то это единственный способ сделать это с помощью неуправляемого кода?