c++ - 如何使用 Eigen 库计算 uint8_t 数组的点积?
问题描述
我想在 C/C++ 中计算两个 uint8 类型数组的点积,天真实现为:
uint64_t dotproduct_u8_naive(uint8_t* a, uint8_t* b, uint32_t len)
{
uint64_t res = 0;
for(uint32_t i=0; i<len; i++) {
res += a[i] * b[i];
}
return res;
}
由于 Eigen 库被声明为使用 SIMD 以实现快速,我想传递两个原始 C 数组,然后分配给 Eigen 的类型,然后计算 dotproduct 结果。实现如下:
uint64_t dotproduct_u8_eigen(uint8_t* a, uint8_t* b, uint32_t len)
{
Eigen::Map<Eigen::Matrix<uint8_t, 1, Eigen::Dynamic, Eigen::RowMajor>> va(a, len);
Eigen::Map<Eigen::Matrix<uint8_t, 1, Eigen::Dynamic, Eigen::RowMajor>> vb(b, len);
uint64_t res = va.dot(vb);
return res;
}
数组a
和b
的元素不是零,但是,dotproduct_u8_eigen
总是返回零,这与来自 的预期结果不同dotproduct_u8_naive()
。这对我来说似乎很奇怪,因为我已经以相同的方式实现了 float32 类型向量点积并得到了正确的结果:
float dotproduct_f32_eigen(float* a, float* b, uint32_t len) {
Eigen::Map<Eigen::Matrix<float, 1, Eigen::Dynamic, Eigen::RowMajor>> va(a, len);
Eigen::Map<Eigen::Matrix<float, 1, Eigen::Dynamic, Eigen::RowMajor>> vb(b, len);
float res = va.dot(vb);
return res;
}
我的问题是:dotproduct_u8_eigen()
错了吗?如何修改dotproduct_u8_eigen()
以获得正确的结果?
我可以通过将 u8 矩阵转换为 uint64 矩阵来获得正确的结果,如下所示,这比简单的实现要慢得多:
uint64_t dotproduct_u8_eigen(uint8_t* a, uint8_t* b, uint32_t len)
{
Eigen::Map<Eigen::Matrix<uint8_t, 1, Eigen::Dynamic, Eigen::RowMajor>> va(a, len);
Eigen::Map<Eigen::Matrix<uint8_t, 1, Eigen::Dynamic, Eigen::RowMajor>> vb(b, len);
Eigen::Matrix<uint64_t, 1, Eigen::Dynamic, Eigen::RowMajor> fa = va.cast<uint64_t>();
Eigen::Matrix<uint64_t, 1, Eigen::Dynamic, Eigen::RowMajor> fb = vb.cast<uint64_t>();
return fa.dot(fb);
}
解决方案
推荐阅读
- python - 提取列表子集以绘制的 Pythonic 方法
- css - 如何更改 nuxt gmap 标记图标大小?
- python - Python:CalledProcessError,命令返回非零退出状态 1
- node.js - 在 NodeJS 中测试 http.Server.close 错误
- javascript - 无法使用 next.js 加载静态资产
- java - 当值出现时使调试器停止 Intelij Idea
- queue - 在达到 100 个队列项计数后,BOT 不会获取 uipath orchestrator 队列项,即使已设置分页值
- javascript - 如何有条件地显示 React JSX 中的元素?
- python - 将 Graph 转换为 SavedModel 后的 Tensorflow FailedPreconditionError
- spring - 在命令式弹簧应用程序中处理弹簧反应器异常