CvMatのアライメントの問題

  • SSE2の転送命令*1は16バイト境界のメモリアドレスを指定しないと例外が飛ぶ
  • CV_MALLOC_ALIGN=>32なのでCvAllocは32バイト境界でメモリアドレスを返してくれるが、CV_DEFAULT_MAT_ROW_ALIGN=>1になっているので、CvMat->data.ptr[CvMat->step * (CvMat->row / n)]*2が16バイト境界になるとは限らない
  • \(^o^)/

対応方法

  1. 16バイト境界になっていなくてもOKな転送命令*3を使う
  2. CV_DEFAULT_MAT_ROW_ALIGN=>16にしてコンパイルする

1は、パフォーマンス的に不利なようだし、2はコンパイルしたOpenCVごと環境に配置する必要があり悲しい。

*1:MOVDQA,_mm_load_*など

*2:行列の各行の先頭アドレス

*3:MOVDQU,_mm_loadu_*など