Я работаю над жидкостным симулятором на С#. Каждому циклу я должен рассчитать скорость жидкости в дискретных точках в пространстве. В рамках этого расчета мне нужно несколько десятков килобайт для пространства царапин для хранения нескольких двумерных массивов (точный размер массивов зависит от некоторых входных данных). Массивы нужны только в течение всего используемого им метода, и существует несколько разных методов, для которых требуется такое пространство для царапин.
Как я вижу, для построения массивов царапин существует несколько различных решений:
-
Используйте 'new' для захвата памяти из кучи каждый раз, когда вызывается метод. Это то, что я делал вначале, однако он оказывает сильное давление на сборщик мусора, а несколько-миллисекундные всплески один или два раза в секунду действительно раздражают.
-
При вызове методов передаются массивы царапин в качестве параметров. Проблема в том, что это заставляет пользователя управлять ими, включая их правильное определение, что является огромной болью. И это затрудняет использование более или менее проблемной памяти, поскольку оно изменяет API.
-
Используйте stackalloc в небезопасном контексте, чтобы выделить память нуля из стека программ. Это будет работать очень хорошо, за исключением того, что мне нужно будет компилировать/небезопасно и постоянно посыпать небезопасные блоки по всему моему коду, чего я бы хотел избежать.
-
Предварительно выделяйте частные массивы один раз, когда программа запускается. Это прекрасно, за исключением того, что я не обязательно знаю размер массивов, которые мне нужны, пока я не смогу посмотреть на некоторые из входных данных. И это становится очень грязным, поскольку вы не можете ограничить область этих частных переменных только одним методом, поэтому они постоянно загрязняют пространство имен. И он плохо масштабируется, так как количество методов, требующих памяти с нуля, увеличивается, поскольку я выделяю много памяти, которая использовала только часть времени.
-
Создайте какой-то центральный пул и выделите массивы с памятью из пула. Основная проблема заключается в том, что я не вижу простого способа выделения массивов динамического размера из центрального пула. Я мог бы использовать начальное смещение и длину и иметь всю память с нуля, по существу, разделяющую один большой массив, но у меня есть много существующего кода, который предполагает double [] s. И я должен быть осторожным, чтобы сделать такой поток потока безопасным.
...
Есть ли у кого-нибудь опыт подобной проблемы? Любые советы/уроки, которые можно предложить из опыта?