与往常一样,我可能在这里遗漏了一些明显的东西。我无法发布整个源代码,因为它与工作相关,但我有一个模板Matrix
类,其中包含一个mulMM
(将矩阵乘以矩阵)函数和一个mulMT
函数(将矩阵乘以转置矩阵)。这已经存在于代码中。我正在尝试添加一个mulMT
专门用于单精度浮点值的函数。我有一个类似的专业,mulMM
它共享相同的前两个函数参数。这是一些示例代码:
#ifdef TARGET_x86_SSE4
template <>
Matrix<Float>& Matrix<Float>::mulMM (const Matrix<Float>& mat1,
const Matrix<Float>& mat2);
template <>
Matrix<Float>& Matrix<Float>::mulMT (const Matrix<Float>& mat1,
const Matrix<Float>& mat2,
const bool softmax);
#endif // no SSE4: use template generic
template <class BT>
Matrix<BT>& Matrix<BT>::mulMM (const Matrix<BT>& mat1,
const Matrix<BT>& mat2) {
// Function code
}
template <class BT>
Matrix<BT>& Matrix<BT>::mulMT (const Matrix<BT>& mat1,
const Matrix<BT>& mat2,
const bool softmax) {
// Function code
}
然后,在一个单独的文件中:
#ifdef TARGET_x86_SSE4
template <>
Matrix<Float>& Matrix<Float>::mulMM (const Matrix<Float>& mat1,
const Matrix<Float>& mat2) {
// Function code
}
template <>
Matrix<Float>& Matrix<Float>::mulMT (const Matrix<Float>& mat1,
const Matrix<Float>& mat2,
const bool softmax) {
// Function code
}
当我调用代码时,mulMM 正确地提取了输入矩阵的值,但是当我调用 mulMT 时,我得到了矩阵维度的随机数。使用调试器,我可以看到矩阵在进入时已正确定义,但一旦我进入函数,值都是错误的。这是我正在使用的一些示例代码:
MatrixFloat mA(4, 5);
MatrixFloat mB(5, 4);
// Code to initialize mA and mB's values.
MatrixFloat mR = mR.mulMM(mA, mB)
// This works fine and correctly find the values for the product.
MatrixFloat mC(4, 4)
// Code to initialize mC
mR = mR.mulMT(mC, mC)
// This fails with a memory access error and stepping into the function reveals
// that this seems to be because mC has dimensions of 84376 x 1 or thereabouts
我已经尝试将这两个值变成不同的 MT。我已经验证,当我的 mulMT for Floats 不存在时,通用的可以工作。我不知道为什么这是在做它正在做的事情。
编辑:为了证明 Float 专业化中的代码不是问题,我将其注释掉。一切正常。我取消了代码的注释。一切仍然有效。我在想,也许 Visual Studio 只是弄糊涂了,没有重新编译一些东西。
进一步编辑:好的......这很奇怪。调试时,当我第一次进入 mulMT 时,它会让我陷入const bool softmax) {
. 如果我尝试 F10,我会遇到异常。如果我按 F11,它会让我陷入ChkStk.asm
. 如果我退出该文件,我就可以访问函数的内部并且所有内容都已正确分配。事实上,只要我不重新编译我的测试程序,我可以不出错地单步执行或运行任意多次。但是,如果我对我的测试程序进行更改并重新编译,行为就会回来。
我比一开始更困惑。
编辑:好的,两天后没有问题,它又出现了。我认为这不是像我之前想的那样,涉及价值观的变化。相反,这是在参数实际实例化之前发生的事情。问题是,我仍然不知道为什么,除了这是我拥有的唯一一个功能,stkchk.asm
如果我F11
在进入该功能后点击它。
UnitTest.exe 中 0x00789adc 的第一次机会异常:0xC0000005:访问冲突读取位置 0xabababab。是我得到的例外。在函数的前面,我进行了几乎相同的调用,只是改变了与运算符一起使用的变量。奇怪的是,调用周围的 try-catch 块并不能防止程序崩溃。