Russian Qt Forum
Октябрь 23, 2018, 07:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Отлов ошибки  (Прочитано 1351 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2050



Просмотр профиля
« Ответ #15 : Август 01, 2018, 18:25 »

ThreadSanitizer не пробовали?
Нет. Не знал о таком. Спасибо, попробую.
Записан
RedDog
Чайник
*
Online Online

Сообщений: 68


Просмотр профиля
« Ответ #16 : Август 01, 2018, 19:26 »

Как только добавляю больше логов, чтобы локализовать проблему на проблемной машине, как она сразу пропадает.
Быть может кто-нибудь подкинет идей что можно ещё попробовать сделать для решения проблемы...
При подобном поведении делал свой логер, который работал в отдельном треде и не мешал (не синхронизировал) основную логику.
Не все и сразу писал, т.к к нему много кто обращался, но не мешал никому.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2050



Просмотр профиля
« Ответ #17 : Август 01, 2018, 22:53 »

Да, в логгере имеется мьютекс, видать, он влиял на результат
Я забыл упомянуть, у меня ещё парсинг (открытие файла) происходит в std::async, но к моменту расчёта парсинг окончен.
ThreadSanitizer показал много мест... Ругнулся также на ui->setup(this). Также ругнулся и на интересующее место.
У меня проблема интерпретации вывода, прошу помочь

Код
C++ (Qt)
   FaceSet result; // using FaceSet = QSet<Face>;
 
   const VolumeNumberList &volumeNumbers = mesh()->volumeNumbers(); // byval QVector
 
   PARALLEL_FOR
   for (int i = 0; i < volumeNumbers.count(); ++i){
       //taking volume byref
       const MeshVolume &volume = mesh()->volume(volumeNumbers.at(i)); // Read of size 2 at 0x7b080008b95c by thread T13:
 
       const auto &volumeRange = volume.range(); // can modify mutable range_
       if (!isVolumeHasToBeChecked(volume, filter) ||
               !hasIntersection(line, volumeRange)){
           continue;
       }
       const auto &shell = volume.shell(); //by value
       const auto &shellFaces = shell.shellFaces(); //by value QVector
       const FaceSet &volumeResult = intersectedFacesWithLine(line, shellFaces); // byval QSet
 
       SCALAR{
           result += volumeResult;
       }
   }
 
   return result;
 
Код
C++ (Qt)
#ifdef _OPENMP
#define PARALLEL_FOR _Pragma("omp parallel for")
#define SCALAR _Pragma("omp critical")
#else
#define PARALLEL_FOR
#define SCALAR
#endif
 
« Последнее редактирование: Август 01, 2018, 23:15 от __Heaven__ » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 10201


Просмотр профиля
« Ответ #18 : Август 02, 2018, 05:15 »

Сначала отключить оmp (там ли собака порылась). Потом изучать intersectedFacesWithLine где, как я понял, и происходит расчет. Лог: не сразу печатать, в параллельном цикле слить в контейнеры (для каждой нитки свой), а по окончании уже в консоль/файл

"Race condition" - возможно переменная одновременно читается/пишется, что может быть не атомарно и повести к ошибке. Ну это всего лишь догадки
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2050



Просмотр профиля
« Ответ #19 : Август 03, 2018, 15:45 »

Вроде, удалось подавить вывод data race санитайзера таким путём:
Указал уровень оптимизаций 0. Таким образом получил более конкретное место. Там производилось 3 обращения подряд к std::map::at заменил их на константные варианты.
Не понимаю, как константность методов влияет.
Псевдокод проблемного места
Код
C++ (Qt)
PARALLEL_FOR
for (i in range) {
   const Triangle triangle(vertices_, i);
   .....
}
 
Triangle::Triangle(vertex_map *vertices, int i)
   : a(vertices.at(i)), b(vertices.at(i+1)), c(vertices.at(i+2))
{}
 
Записан
RedDog
Чайник
*
Online Online

Сообщений: 68


Просмотр профиля
« Ответ #20 : Август 03, 2018, 21:42 »

vertices.at(...) потокобезопасны?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 10201


Просмотр профиля
« Ответ #21 : Август 04, 2018, 12:54 »

Псевдокод проблемного места
Код
C++ (Qt)
PARALLEL_FOR
for (i in range) {
   const Triangle triangle(vertices_, i);
   .....
}
 
Triangle::Triangle(vertex_map *vertices, int i)
   : a(vertices.at(i)), b(vertices.at(i+1)), c(vertices.at(i+2))
{}
 
Неудачный псевдокод, здесь важно является ли for первым циклом (будет ли omp сама заниматься переменной "i"), тогда напр пройти с шагом 3 нельзя. И не видно что заменено на константные методы (vertex_map не const, значит будет вызываться неконстантный at). К слову: если at выбросит исключение - оно поймается в одной из ниток omp (необязательно главной).

А вообще конечно вряд ли "то место". Если бы что не так с at  - там было бы "костей не собрать", не то что редкий вылет.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2050



Просмотр профиля
« Ответ #22 : Август 05, 2018, 14:54 »

vertices.at(...) потокобезопасны?

Не знаю. Потокобезопасен ли неконстантный std::map::at?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2050



Просмотр профиля
« Ответ #23 : Август 05, 2018, 14:56 »

Исключения в at бросаться не должны - все запрашиваемые элементы существуют
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 10201


Просмотр профиля
« Ответ #24 : Август 06, 2018, 03:50 »

Не знаю. Потокобезопасен ли неконстантный std::map::at?
Ну если "все эл-ты существуют" - то скорее всего да (а по-хорошему в доке указывается "thread-safe").  Но чего Вы уперлись в это место? Какой-то санитар на него указал? Так верить ему необязательно. Ищите запись, ошибка обязательно связана с ней
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  

Страница сгенерирована за 0.121 секунд. Запросов: 22.