2014-12-08 2 views
1

Я работаю над инструментом обработки звука, который я хотел бы построить с использованием потока данных TPL. Сам поток данных будет состоять из звуковых образцов, передаваемых между блоками обработки звука. Эти образцы обычно будут иметь размер в несколько К (float[]/byte[] с элементами от 1 до 4 тыс.). Поток данных, таким образом, простой трубопровод, который выглядит следующим образом:Утилизация данных потока данных TPL

SourceBlock<byte[]> 
    -> TransformBlock<byte[], float[]> 
     -> TransformBlock<float[], float[]> 
      -> ... 

Некоторые из блоков может работать чисто «на месте», т.е. мутирует входные данные, в то время как другие должны создать новые образцы. Время обработки каждого блока может варьироваться в зависимости от данных на входе.

Я не хочу постоянно выделять новые массивы и полагаться на сборщик мусора, чтобы заботиться об утилизации объектов. Я хочу использовать параллельное выполнение блоков и, следовательно, не хочу ограничивать цепочку обработкой данных последовательно (в этом случае мне не понадобится TPL в любом случае). Мне не нужны блоки обработки, чтобы запускать параллельную обработку (я в порядке с одним процессом на блок в любой момент времени).

Какая была бы лучшая схема для управления количеством образцов в конвейере в данный момент времени и повторная выборка образцов/массивов больше не использовалась?

+2

«Я не хочу все время выделять новые массивы и полагаться на сборщик мусора, чтобы заботиться об утилизации объектов». Почему это требование вашего решения? Является ли сбор мусора заметным образом влияющим на вашу производительность, и если да, то какую производительность вы нацеливаете? –

+0

Я хочу, чтобы этот код мог работать на телефонах с использованием xamarin, поэтому важна память. трудно проверить все сценарии (особенно аппаратные средства), поэтому им необходимо предварительно идентифицировать и устранить возможные проблемы. –

+0

Моя первоначальная мысль заключалась в том, что процессоры производят две данные, один результат обработки и один «мусор», подлежащий переработке. последний затем будет передан на процессоры вверх по потоку (эффективно создавая петлю в сетке). Не уверен, что это жизнеспособный вариант. –

ответ

1

Если ваша цель состоит в том, чтобы повторно использовать массивы вместо того, чтобы всегда создавать новые и имеющие GC собирать их нужно использовать ObjectPool:

Узор пула объектов представляют собой программное обеспечение порождающих шаблоны проектирования дизайна, который использует набор инициализированных объектов, готовых к использованию, - «пул» - вместо того, чтобы распределять и уничтожать их по требованию. Клиент пула будет запрашивать объект из пула и выполнять операции с возвращенным объектом. Когда клиент закончил, он возвращает объект в пул, а не уничтожает его; это можно сделать вручную или автоматически.

К сожалению, вам, вероятно, потребуется реализовать это самостоятельно и сделать его потокобезопасным.

+0

Это звучит как хорошее решение. Я думаю, что я должен попытаться оптимизировать переработку на основе запрашивающей нити (например, что делает concurrentBag). Как вы думаете ? –

+0

@LauLu Вы входите на территорию микро-оптимизации ... вы даже знаете, использует ли блок потока данных TPL выделенный поток для каждого элемента? Я думаю, что BlockingCollection вокруг ConcurrentQueue просто отлично. – i3arnon

+0

Я попробовал ObjectPool, и, как только я понял, это делает работу, спасибо. Petformance-wise практически не влияет, но теперь я использую гораздо меньше памяти. –

 Смежные вопросы

  • Нет связанных вопросов^_^