Нужна помощь с DLL

 

Тестирую многопоточные вычисления (OpenMP) с использованием динамической библиотеки.
Библиотеку для расчетов писал сам в Visual Studio 2019.
Библиотека содержит единственную функцию, которая перемножает два матрицы.

Готовое решение работает, но есть проблема.
1. Решение отлично работает на матрицах с большой размерностью. И даёт ускорение расчетов в 8-10 раз.



2. Решение отлично работает в режиме отладки step-by-step в MetaEditor. Без каких либо ошибок.

3. Но на малых размерностях матриц терминал крэшится без каких либо записей об ошибках в логах.

 Соответственно нужна помощь  - куда дальше копать?
 На какой стороне ошибка, на стороне терминала или на стороне библиотеки.

Файлы проекта библиотеки прилагаю.

Файлы:
fnnmql5.zip  4947 kb
 

Sleep(200) поставь в конце скрипта

ХЗ, как omp с потоками работает, но основному потоку управление передает до того, как созданные потоки ресурсы освобождают. Далее:

  1. У тебя скрипт закончился.
  2. Кроме него, никто dll не использует, поэтому терминал делает FreeLibrary и ОС убирает ее из адресного пространства терминала.
  3. А вот тут, код незакрытого потока переходит к ExitThread и упс, у тебя нарушение прав доступа и крах терминала.
ИМХО, но очень похоже на это.
 
Vladimir Simakov:

Sleep(200) поставь в конце скрипта

ХЗ, как omp с потоками работает, но основному потоку управление передает до того, как созданные потоки ресурсы освобождают. Далее:

  1. У тебя скрипт закончился.
  2. Кроме него, никто dll не использует, поэтому терминал делает FreeLibrary и ОС убирает ее из адресного пространства терминала.
  3. А вот тут, код незакрытого потока переходит к ExitThread и упс, у тебя нарушение прав доступа и крах терминала.
ИМХО, но очень похоже на это.

Sleep(200) помогает, но это конкретный костыль.
Проблема не в потоках и их синхронизации.
По умолчанию при распараллеливании цикла for в OpenMP происходит барьерная синхронизация потоков. Даже включение принудительной барьерной синхронизации не помогает. 

Вероятнее всего проблема возникает при выгрузке dll из терминала. Раз приходится делать паузу после вызова функции dll, то похоже, что терминал не дожидается нормальной выгрузки dll.
Есть запись в событиях ОС:

Имя сбойного приложения: terminal64.exe, версия: 5.0.0.2615, метка времени: 0x03e04400
Имя сбойного модуля: VCOMP140.DLL_unloaded, версия: 14.27.29016.0, метка времени: 0x5ee83a50
......

Путь сбойного модуля: VCOMP140.DLL

Пробовал распараллеливать потоки посредством <thread>, результат такой же.

Пока буду делать паузу перед завершением программы.
Результат на малых размерностях массивов меня устраивает:


 
Vladimir Mikhailov:

Sleep(200) помогает, но это конкретный костыль.
Проблема не в потоках и их синхронизации.
По умолчанию при распараллеливании цикла for в OpenMP происходит барьерная синхронизация потоков. Даже включение принудительной барьерной синхронизации не помогает. 

Вероятнее всего проблема возникает при выгрузке dll из терминала. Раз приходится делать паузу после вызова функции dll, то похоже, что терминал не дожидается нормальной выгрузки dll.
Есть запись в событиях ОС:

Пробовал распараллеливать потоки посредством <thread>, результат такой же.

Пока буду делать паузу перед завершением программы.
Результат на малых размерностях массивов меня устраивает:


https://stackoverrun.com/ru/q/9492992

Если с буржуйским дружишь, то, как раз твоя проблема. Решение не проверял.

 

Всем спасибо за идеи, особенно Maxim Kuznetsov.

Решение заключается в отказе от выгрузки dll при завершении скрипта или советника.
Dll будет загружена, пока запущен терминал. Любые другие скрипты и советники могут обращаться к этой dll.
После закрытия терминала dll выгружается.

Итоговый вариант dll прилагаю, может кому понадобится.

Файлы:
ompmql.zip  4633 kb
Причина обращения: