I'm implementing a tangent distance based OCR solution for the iPhone, which heavily relies on fast multiplication of floating-point matrices of size 253x7. For the proof of concept, I've implemented my own naive matrix routines like this:
Matrix operator*(const Matrix& matrix) const {
if(cols != matrix.rows) throw "cant multiply!";
Matrix result(rows, matrix.cols);
for(int i = 0; i < result.rows; i++){
for(int j = 0; j < result.cols; j++){
T tmp = 0;
for(int k = 0; k < cols; k++){
tmp += at(i,k) * matrix.at(k,j);
}
result.at(i,j) = tmp;
}
}
return result;
}
As you can see, it's pretty basic. After the PoC performed well, I've decided to push the performance limits further, by incorporating the Accelerate Framework's matrix multiplication (which presumably uses SIMD, and other fancy stuff, to do the heavy lifting...):
Matrix operator*(const Matrix& m) const {
if(cols != m.rows) throw "cant multiply!";
Matrix result(rows,m.cols);
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, rows, m.cols, cols, 1, matrix, cols, m.matrix, m.cols, 1, result.matrix, result.cols);
return result;
}
Shockingly (at least for me), the above code took double the time to multiply the matrices! I've tried using single precision instead of double, cause I was suspicious that it was something related with the CPU's word-size (32 bit float vs. 64 bit double on a 32 bit ARM), but had no performance gain...
What am I doing wrong? Are my 253x7 matrices too small for noticeable performance boost over the naive implementation?