【发布时间】:2014-02-25 23:17:07
【问题描述】:
自从我使用 MSVC 2013 以来,我的应用程序在执行以下代码时崩溃(稀疏矩阵乘以向量,伪代码:A = this * pVector):
complex<double> x = (A.getValue(lRow) + (mValues[lIdx] * pVectorB->getValue(lCol)));
在我使用 MSVC 2005 之前,应用程序运行良好。
抛出异常 (First-chance exception at 0x000000014075D1D2 in psc64.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.)。
我跟踪程序集以:
addpd xmm6, xmmword ptr [rax+rbx*8]
它仅在优化 /O2(最大化速度)时崩溃,但在没有优化 /Od 时不会崩溃。
我还可以在将代码 (coutpVectorB->getValue(lCol) 时避免崩溃。
我相信未初始化变量可能是一些问题。但我找不到任何东西。因此,我研究了拆卸。
我检查 XMM6 和 ptr [rax+rbx*8]。没有崩溃(使用 cout除了 XMM6 和 ptr [rax+rbx*8] 的值之外,我还有什么需要寻找的吗?
我很长一段时间以来一直在寻找问题,但找不到任何提示来追踪问题到我必须更正的代码行。
非常感谢任何帮助。谢谢。
getValue 的代码:
template <class T> class Vector
{ const T& getValue(const int pIdx) const
{
if(false == checkBounds(pIdx)){
throw MathException(__FILE__, __LINE__, "T& Vector<class T>::getValue(const pIdx): checkBounds fails pIdx = %i", pIdx);
}
return mVal[pIdx];
}
bool checkBounds(const int pIdx)const
{
bool ret = true;
if(pIdx >= mMaxSize){
DBG_SEVERE2("pIdx >= mMaxSize, pIdx = %i, mMaxSize = %i", pIdx, mMaxSize);
ret = false;
}
if(pIdx < 0){
DBG_SEVERE1("pIdx < 0, pIdx = %i", pIdx);
ret = false;
}
return ret;
}
}
mVal的配置:
void* lTmp= calloc((4 * sizeof(complex<double>))+4, 1);
((char*)lTmp)[0] = 0xC;
((char*)lTmp)[1] = 0xC;
((char*)lTmp)[(4 * sizeof(complex<double>)) + 2] = 0xC;
((char*)lTmp)[(4 * sizeof(complex<double>)) + 3] = 0xC;
mVal= (void*)(((char*)lTmp) + 2)
解决方案:
正如建议的那样,它可以在所需数组 (mVal) 前后没有 2 个字节的情况下工作。但它也适用于数组前后的 16 字节的倍数。
【问题讨论】:
-
你用汇编写乘法吗?
-
能贴出getValue方法的源码吗?
-
乘法不是汇编。它是纯 C++,使用复杂的
函数。 -
那么我认为显示更多的源代码会更有帮助,一个独立的、可编译的、sn-p 的代码来证明问题是理想的。
-
请参阅stackoverflow.com/questions/13013717/… 这里很可能存在对齐问题。
标签: c++ visual-c++ optimization assembly sse