2010-10-21 5 views
3

У меня есть код F #, вычисляющий поток жидкости. Код состоит из двух проектов. Основная библиотека и проект для запуска моделирования. Когда я запускаю параметрическое исследование, напримерF # - Сфера применения переменных

open CoreLibrary 
for lbmViscosity in [0.1] do 
    for Re in [0.001; 0.5] do 
    for lbmD in [6.;5.;4.;3.;2.5;2.;1.5;1.;0.8;0.6;0.4;0.2] do 
     simulation setup 
     let result = call CoreLibrary 
     save result to file 

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

open CoreLibrary 
for lbmViscosity in [0.1] do 
    for Re in [0.1; 0.001; 0.5] do 
    for lbmD in [6.;5.;4.;3.;2.5;2.;1.5;1.;0.8;0.6;0.4;0.2] do 
     simulation setup 
     let result = call CoreLibrary 
     save result to file 

Тогда для Re = 0,001 я получаю неправильный результат. Я также попробовал Array.iter вместо цикла с тем же результатом. Когда я компилирую свой код и запускаю его как exe с разными входными параметрами, тогда он работает хорошо.

Есть ли что-нибудь, что может привести к неправильному результату в стороне от мутации? Может быть, это ошибка сборщика мусора? И есть ли какая-нибудь команда, которая полностью очистила бы память в определенном месте? Что-то вроде:

open CoreLibrary 
for lbmViscosity in [0.1] do 
    for Re in [0.1; 0.001; 0.5] do 
    for lbmD in [6.;5.;4.;3.;2.5;2.;1.5;1.;0.8;0.6;0.4;0.2] do 
     clean everything 
     simulation setup 
     let result = call CoreLibrary 
     save result to file 

Я мутирую значения только в основной библиотеке, не в циклах for. Поэтому я ожидал бы, что как только цикл перейдет к следующему циклу или как только закончится Array.iter, все внутри будет стерто.

Спасибо за любую помощь, подсказка и т.д. :)


Так что я нашел то, что было неправильно - горный массив был прав! :) В coreLibrary мы используем ConcurrentDictionary. Мы хотели использовать Records вместо Classes (быть функциональным: D), а записи не позволяют создавать словарь внутри класса, поэтому словарь был создан вне класса и связан с записью функциями-членами. Поэтому, как только dll был загружен, словарь был создан и остался живым навсегда ... Теперь мы изменили запись на класс, и все работает нормально. Большое спасибо за ваши советы

+0

Просто удаление строки 'open CoreLibrary' не должно оказывать никакого влияния на код. Можете ли вы вставить точные строки кода из внутреннего цикла или создать минимальный набор исходных кодов, имеющих такую ​​же проблему? –

+0

Открытая библиотека CoreLibrary должна быть везде. Я это исправил. Я не уверен, что смогу воспроизвести ошибку, поскольку код будет сложным. Я попытаюсь упростить код и разместить его как zip. –

+2

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

ответ

1

Итак, я нашел, что не так - массив был прав! :) В coreLibrary мы используем ConcurrentDictionary. Мы хотели использовать Records вместо Classes (быть функциональным: D), а записи не позволяют создавать словарь внутри класса, поэтому словарь был создан вне класса и связан с записью функциями-членами. Поэтому, как только dll был загружен, словарь был создан и остался живым навсегда ... Теперь мы изменили запись на класс, и все работает нормально. Большое спасибо за ваши советы

0

Какие типы данных вы используете? Возможно ли, что типы с плавающей запятой, которые вы используете, вводят ошибки представления? Что представляет собой «правильный» и «неправильный» вывод?

Как правило, открытие или отсутствие открытия библиотеки не окажет никакого влияния на результат вычисления (при условии, что код все еще компилируется!).

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