Nano Hash - криптовалюты, майнинг, программирование

помогите мне рассуждать о потоках F #

Дурачившись с некоторым F # (через MonoDevelop), я написал процедуру, которая перечисляет файлы в каталоге с одним потоком:

let rec loop (path:string) = 
  Array.append
    (
        path |> Directory.GetFiles
    )
    (
        path 
        |> Directory.GetDirectories
        |> Array.map loop
        |> Array.concat
    )

А затем его асинхронная версия:

let rec loopPar (path:string) = 
  Array.append
    ( 
        path |> Directory.GetFiles
    )
    ( 
        let paths = path |> Directory.GetDirectories
        if paths <> [||] then
            [| for p in paths -> async { return (loopPar p) } |]
            |> Async.Parallel
            |> Async.RunSynchronously 
            |> Array.concat
        else 
            [||]
    ) 

В небольших каталогах асинхронная версия работает нормально. В больших каталогах (например, во многих тысячах каталогов и файлов) асинхронная версия, похоже, зависает. Что мне не хватает?

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

Как на самом деле работают эти потоки?

Изменить:

Согласно этому документу:

Mono> = 2.8.x имеет новый пул потоков, который намного сложнее заблокировать. Если вы получаете взаимоблокировку пула потоков, скорее всего, ваша программа пытается зайти в тупик.

:D


  • WRT в тупик, что очень вероятно. Рассмотрим случай, когда для завершения каталога папки B вам нужно добавить X потоков в пул потоков. Однако это блокируется до тех пор, пока не завершатся предыдущие потоки; за исключением того, что они заблокированы из-за необходимости создавать больше потоков в пуле потоков ... 29.12.2010
  • Для управляемых трассировок стека зависшей программы $ PID, kill -QUIT $ PID и проверьте вывод консоли программы. Для собственных трассировок стека gdb прикрепляет $ PID, затем t a a bt. 31.12.2010

Ответы:


1

Да, скорее всего, вы перегружаете пул потоков Mono, что снижает производительность вашей системы.

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

ThreadPool - это существующий набор потоков для коротких задач, и это то, что пользователи F # используют для своих рабочих процессов Async. Всякий раз, когда вы выполняете операцию F # Async, она просто делегирует действие пулу потоков.

Проблема в том, что происходит, когда вы запускаете тысячи асинхронных действий в F # одновременно? Наивная реализация просто порождает столько потоков, сколько необходимо. Однако, если вам нужно 1000 потоков, это означает, что вам нужно 1000 x 4 МБ стека. Даже если бы у вас было достаточно памяти для всех стеков, ваш процессор постоянно переключался бы между разными потоками. (И подкачки локальных стеков в память и из памяти.)

IIRC, реализация Windows .NET была достаточно умной, чтобы не порождать тонны потоков, а просто ставить работу в очередь до тех пор, пока не появилось несколько резервных потоков для выполнения действий. Другими словами, он будет добавлять потоки до тех пор, пока у него не будет фиксированного числа, и просто будет их использовать. Однако я не знаю, как реализован пул потоков Mono.

tl; dr: Это работает, как ожидалось.

29.12.2010
  • Думаю, вы правы: здесь, с Mono, fsi.exe запускает кучу потоков, но поскольку они в основном ничего не делают, система вообще не нагружается ... 29.12.2010

  • 2

    Крис, наверное, прав. Другой аспект, который следует учитывать, заключается в том, что файловые системы не являются фиксированными вещами - эти каталоги с тысячами файлов меняются, когда вы пытаетесь обработать список? Если да, то это могло вызвать где-то состояние гонки.

    29.12.2010
  • Это несистемные каталоги, в которых ничего интересного не происходит, но это может стать проблемой для настоящего приложения. Я предполагаю, что это одна из причин, по которой методы System.IO.Directory возвращают массивы вместо списков: файловая система в любом случае изменяема и не контролируется средой выполнения. 29.12.2010
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..