我有一个C ++程序,主要执行矩阵乘法,加法等等。
问题是,当计算执行约300万次时会发生EXC_BAD_ACCESS。
当问题执行数百万次和几个小时时,是否会出现任何问题?
该计划的详情:
程序只是对不同值范围的计算,因此它同时在6个线程上执行。线程之间没有资源共享。
程序似乎没有明显的问题,因为:
关于矩阵乘法:
有时矩阵的大小约为2 * 2乘以2 * 1000。
矩阵的元素是自定义的复数类。
元素的值由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
};
非常感谢!
非常欢迎任何可能的崩溃原因!
答案 0 :(得分:2)
EXC_BAD_ACCESS表示您取消引用了一个指针,该指针未指向进程的当前内存空间。这是您的代码中的错误。在调试器下运行它直到它失败,然后查看它失败的语句中的变量值。它可能很简单或非常微妙。
答案 1 :(得分:1)
您的帖子中的信息太少,无法做出决定性的答案。但是,现在可能没有任何信息可以更改它,您需要更仔细地调试案例。这就是我要做的事。
要进行调试,您需要重复性。但是......你说你使用的是随机数。看起来,你的程序所做的是一些科学计算。在大多数情况下,你实际上并不需要“真正的”随机性,而是通过统计测试的“可重复”随机性 - 随机性,但是你有足够的数据来重置随机数发生器,这样它就能产生与中的完全相同的结果。上次运行。为此,您可以在每次开始新的计算块时写下当前的RNG状态(例如种子)。
现在,编写一段代码,每隔几分钟存储一次重启计算所需的所有状态(包括RNG),然后运行程序。这样,如果您的代码崩溃,您将能够以相同的精确状态重新启动计算,并在不等待数百万次迭代的情况下达到崩溃的程度。我在这里强烈假设,除了RNG之外,您的代码不依赖于任何其他类型的外部状态(例如,网络活动,IO,进程调度程序在调度线程时做出某些选择......)
使用这种数据,可以更容易地测试问题是由于机器故障(过热,坏内存等)造成的。只需在崩溃之前用最后一个状态重新启动计算 - 最好是让机器冷却后,可能重新启动它......如果你遇到另一个崩溃(每次你尝试重启代码时都会发生),这很可能是因为它你代码中的一个错误。
如果没有,我们仍然不能说它是机器故障 - 您的代码可能(通过纯粹的意外/代码中的错误)崩溃,因为未定义的行为取决于您控制之外的因素。示例包括在很少采用的代码路径中使用未初始化的指针:它有时可能会丢失访问权限,如果纯粹运气指针指向您分配的内存,则不会被注意到。试试valgrind,这可能是检查内存问题的最佳工具......除了它会减慢执行速度以至于您再次希望从已知可疑状态(崩溃前的最后一个状态)重新运行计算而不是等待数百万次迭代。我看到了5x到100x的减速。
与此同时,尝试在另一台计算机上运行您的代码。如果在经过相似次数的迭代后你也会崩溃(为了确保等待至少比在原始机器上崩溃多3倍的迭代次数),那么很可能它是你代码中的错误。
快乐的黑客攻击!
答案 2 :(得分:0)
有限精度的计算在几百万次迭代后失败?这可能是累积的四舍五入错误。问题是,那些通常表现为零或其他数学误差。 EXC_BAD_ACCESS
不是。但是,有一种情况可能发生:当您将数学结果用作数组索引时。