Влияние вызова внешней функции C на процессорное время в OpenModelica

#openmp #modelica #openmodelica

Вопрос:

мы реализовали функцию внешней задержки в C и хотим напомнить о ней в нашей модели Modelica (линия передачи). наша цель-ускорить процессорное время. к сожалению, это увеличило время процессора.
Мои вопросы таковы:

  1. Увеличивает ли вызов внешней функции время моделирования в Modelica по сравнению с существующей встроенной задержкой?
  2. Значительно ли увеличивает время моделирования использование внешнего объекта в OpenModelica?
  3. Как скомпилировать только нашу внешнюю функцию с открытым MP (как мы можем добавить флаг-fopenmp только для внешней функции)? Следующая ошибка (см. Рисунок ниже) возникла, когда мы не использовали вышеуказанный флаг (как показано на рисунке ниже), но, используя флаг с начала компиляции, увеличили время моделирования, в то время как мы ожидали меньшего времени моделирования. PS: наша функция скомпилирована как библиотека, в которую мы включили флаг-fopenmp. введите описание изображения здесь
    введите описание изображения здесь

Ответ №1:

  1. Увеличивает ли вызов внешней функции время моделирования в Modelica по сравнению с существующей встроенной задержкой?

Нет. Это очень простой вызов, и в Modelica вам разрешено использовать внешние вызовы функций только в четко определенные моменты времени. Однако у вас может возникнуть проблема, если вы введете алгебраические циклы.

  1. Значительно ли увеличивает время моделирования использование внешнего объекта в OpenModelica?

Нет. Это всего лишь указатель. Если что-то происходит медленно, то это происходит внутри самого внешнего объекта или того, как он используется.

  1. Как скомпилировать только нашу внешнюю функцию с открытым 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 мс). Поскольку это для линий передачи, я предполагаю, что функция вызывается много раз; вы получаете накладные расходы за каждый вызов функции. Вам нужно либо очень много независимых задач, либо несколько задач, которые занимают очень много времени (секунд), чтобы извлечь выгоду из распараллеливания.