#openmp #modelica #openmodelica
Вопрос:
мы реализовали функцию внешней задержки в C и хотим напомнить о ней в нашей модели Modelica (линия передачи). наша цель-ускорить процессорное время. к сожалению, это увеличило время процессора.
Мои вопросы таковы:
- Увеличивает ли вызов внешней функции время моделирования в Modelica по сравнению с существующей встроенной задержкой?
- Значительно ли увеличивает время моделирования использование внешнего объекта в OpenModelica?
- Как скомпилировать только нашу внешнюю функцию с открытым MP (как мы можем добавить флаг-fopenmp только для внешней функции)? Следующая ошибка (см. Рисунок ниже) возникла, когда мы не использовали вышеуказанный флаг (как показано на рисунке ниже), но, используя флаг с начала компиляции, увеличили время моделирования, в то время как мы ожидали меньшего времени моделирования. PS: наша функция скомпилирована как библиотека, в которую мы включили флаг-fopenmp.
Ответ №1:
- Увеличивает ли вызов внешней функции время моделирования в Modelica по сравнению с существующей встроенной задержкой?
Нет. Это очень простой вызов, и в Modelica вам разрешено использовать внешние вызовы функций только в четко определенные моменты времени. Однако у вас может возникнуть проблема, если вы введете алгебраические циклы.
- Значительно ли увеличивает время моделирования использование внешнего объекта в OpenModelica?
Нет. Это всего лишь указатель. Если что-то происходит медленно, то это происходит внутри самого внешнего объекта или того, как он используется.
- Как скомпилировать только нашу внешнюю функцию с открытым MP (как мы можем добавить флаг-fopenmp только для внешней функции): при связывании исходных файлов? следующая ошибка возникла, когда мы не использовали вышеуказанный флаг, но, используя флаг с начала компиляции, увеличили время моделирования, в то время как мы ожидали меньшего времени моделирования. PS: наша функция скомпилирована как библиотека, в которую мы включили флаг-fopenmp.
Вы заранее компилируете библиотеку и добавляете флаг-fopenmp во флаги компоновщика или в аннотацию библиотеки внешней функции. Работает ли код медленнее при использовании только 1 потока в OpenMP? Писать быстрый параллельный код сложно, и OpenMP скрывает много деталей, поэтому трудно понять, почему он работает медленнее.
Комментарии:
1. спасибо, @sjoelund.se, что касается вашего третьего пункта, как мы можем добавить флаг-fopenmp к флагу компоновщика
2. В OMEdit в разделе Инструменты -> Интерфейс командной строки OMC вы можете ввести >
setLinkerFlags("-fopenmp")
. Однако это активно только для текущего сеанса. В противном случае вы можете использовать аннотацию:external "C" annotation(Library="-fopenmp");
но это может быть непереносимо для разных инструментов (возможно, компилятор не использует-fopenmp
флаг).3. наша внешняя функция содержит цикл с 3 независимыми итерациями, мы решили распараллелить их (используя 3 потока) и ожидали улучшения, однако моделирование заняло больше времени. у тебя есть какие-нибудь идеи? (мы добавили флаг компоновщика» setLinkerFlags(«-fopenmp»), мы попытались изменить переменную среды OMP_NUM_THREAD, но это не улучшило процессорное время).
4. Вы получаете накладные расходы на создание потока, что, вероятно, затмевает время, необходимое для завершения 1 итерации. Знаете ли вы, сколько времени занимает каждая итерация? Использование SIMD может быть лучше, чем потоки. Видишь lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux по некоторым оценкам, создание потока соединение (9~200 мс). Поскольку это для линий передачи, я предполагаю, что функция вызывается много раз; вы получаете накладные расходы за каждый вызов функции. Вам нужно либо очень много независимых задач, либо несколько задач, которые занимают очень много времени (секунд), чтобы извлечь выгоду из распараллеливания.