многопоточность — стабильность программы на C ++ после миллионов выполнений

У меня есть программа на C ++, которая выполняет в основном матричные умножения, сложения и так далее.

Проблема в том, что EXC_BAD_ACCESS происходит, когда вычисления выполняются около 3 миллионов раз.

Есть ли возможные проблемы, которые могут возникнуть, когда проблема выполняется миллионы раз и в течение нескольких часов?

Детали программы:

Программа просто выполняет вычисления в разных диапазонах значений, поэтому она выполняется одновременно для 6 потоков. Нет разделения ресурсов между потоками.

Кажется, в программе нет явных проблем, поскольку:

  1. утечки памяти нет, я подтвердил это с помощью инструментов, а объем памяти программы стабилен.
  2. программа может выполняться по крайней мере 2 миллиона раз в каждом потоке без каких-либо проблем, но почти гарантировано, что исключение EXC_BAD_ACCESS возникает некоторое время, в каком-то потоке. (исключение случается в моих 2 попытках программы (2/2))

О матричном умножении:

Иногда размер матриц составляет около 2 * 2, умножается на 2 * 1000.

Элементами матрицы является пользовательский класс Complex Number.

значения элементов случайным образом генерируются rand () и преобразуются в float.

структура такая:

class Complex
{
private:
float _real, _imag;
public:
// getters, setters and overloaded operators
};

class Matrix
{
private:
Complex **_values;
int _row,_col;
public:
getters, setters and overloaded operators
};

Большое спасибо!

Любая возможная причина аварии приветствуется!

1

Решение

EXC_BAD_ACCESS означает, что вы разыменовали указатель, который не указывает на текущую область памяти вашего процесса. Это ошибка в вашем коде. Запускайте его в отладчике до тех пор, пока он не выйдет из строя, а затем посмотрите на значения переменных в операторе, где он выходит из строя. Это может быть просто или очень тонко.

2

Другие решения

В вашем сообщении слишком мало информации, чтобы сделать решающий ответ. Однако может случиться так, что никакая информация, доступная вам сейчас, не изменит ее, и вам нужно отладить дело более тщательно. Вот что я сделаю.

Для отладки требуется повторяемость. Но … вы говорите, что используете случайные числа. Тем не менее, кажется, что ваша программа выполняет некоторые научные вычисления. В большинстве случаев вам на самом деле не нужна «истинная» случайность, а «повторяемая» случайность — случайность, которая проходит статистические тесты, но когда у вас достаточно данных для сброса генератора случайных чисел, чтобы он давал точно такие же результаты, как в предыдущий прогон. Для этого вы можете просто записывать текущее состояние ГСЧ (например, начальное число) каждый раз, когда начинаете новый блок вычислений.

Теперь напишите какой-нибудь фрагмент кода, который будет хранить все состояния, необходимые для перезапуска вычислений (включая RNG), каждые несколько минут и запускать программу. Таким образом, если ваш код дает сбой, вы сможете перезапустить вычисления с тем же самым точным состоянием и добраться до точки, где он потерпел крах, не дожидаясь миллионов итераций. Я полагаю здесь сильное предположение, что кроме RNG ваш код не зависит от какого-либо другого внешнего состояния (например, сетевой активности, ввода-вывода, планировщика процессов, делающего определенные выборы при планировании ваших потоков…)

С такими данными будет легче проверить, связана ли проблема с неисправностью машины (перегрев, плохая память и т. Д.). Просто перезапустите вычисление с последним состоянием перед сбоем — предпочтительно после того, как машина остынет, возможно, перезапустите ее … если вы столкнетесь с другим сбоем (и это будет происходить каждый раз, когда вы пытаетесь перезапустить код), вполне вероятно, что это происходит из-за ошибка в вашем коде.

Если нет, мы все равно не можем сказать, что это машинная ошибка — ваш код может (из-за чистой случайности / ошибки в коде) зависнуть из-за неопределенного поведения, которое зависит от факторов, находящихся вне вашего контроля. Примеры включают использование неинициализированного указателя в редко используемом пути кода: он может иногда давать неправильный доступ и остаться незамеченным, если по чистой случайности указатель указывает на выделенную вами память. Пытаться Valgrind, это, вероятно, лучший инструмент для проверки проблем с памятью… за исключением того, что он настолько сильно замедляет выполнение, что вы снова предпочтете перезапускать вычисления из состояния, которое, как известно, является подозрительным (последнее состояние перед сбоем) вместо ожидания миллионов итераций. Я видел замедления от 5х до 100х.

А пока попробуйте запустить свой код на другом компьютере. Если вы также получите сбои после аналогичного числа итераций (чтобы быть уверенным, подождите как минимум в 3 раза больше итераций, чем потребовалось для сбоя на исходном компьютере), то вполне вероятно, что это ошибка в вашем коде.

Счастливого взлома!

1

Вычисления с конечной точностью, которые не выполняются после нескольких миллионов итераций? Это может быть накоплено ошибка округления. Проблема в том, что они обычно проявляются как деление на ноль или другие математические ошибки. EXC_BAD_ACCESS не является. Однако есть один случай, когда это может произойти: когда вы используете математический результат в качестве индекса массива.

0
По вопросам рекламы [email protected]