三元向量的快速内积
Fast inner product of ternary vectors
考虑两个向量,A 和 B,大小为 n,7 <= n <<em> = 23。A 和 B 都仅由 -1、0 和 1 组成。
我需要一个快速算法来计算 A 和 B 的内积。
到目前为止,我已经考虑使用以下编码将符号和值存储在单独的uint32_t
中:
- 符号 0,值 0 → 0
- 符号 0,值 1 → 1
- 符号 1,值 1 → -1。
我想到的C++实现如下所示:
struct ternary_vector {
uint32_t sign, value;
};
int inner_product(const ternary_vector & a, const ternary_vector & b) {
uint32_t psign = a.sign ^ b.sign;
uint32_t pvalue = a.value & b.value;
psign &= pvalue;
pvalue ^= psign;
return __builtin_popcount(pvalue) - __builtin_popcount(psign);
}
这工作得相当好,但我不确定是否有可能做得更好。非常感谢对此事的任何评论。
有 2 uint32_t
,但我认为你的实际计算有点浪费
只是几个小点:
我不确定参考(通过
const &
获得a
和b
)-与将它们放在堆栈上相比,这增加了间接程度。当代码这么小(也许有几个时钟)时,这很重要。尝试按值传递,看看你得到了什么不幸的是,
__builtin_popcount
效率非常低。我自己也用过它,但发现即使是我编写的一个非常基本的实现也比这快得多。但是 - 这取决于平台。
基本上,如果平台具有硬件popcount实现,则__builtin_popcount
使用它。如果没有 - 它使用非常低效的替代品。
这里的一个严重问题是重用正向量和负向量的psign
和pvalue
变量。以这种方式混淆代码既没有对编译器也没有好处。
您是否可以在std::bitset<2>
中编码您的三元状态并根据and
定义乘积?例如,如果三元类型为:
1 = P = (1, 1)
0 = Z = (0, 0)
-1 = M = (1, 0) or (0, 1)
我相信您可以将他们的产品定义为:
1 * 1 = 1 => P * P = P => (1, 1) & (1, 1) = (1, 1) = P
1 * 0 = 0 => P * Z = Z => (1, 1) & (0, 0) = (0, 0) = Z
1 * -1 = -1 => P * M = M => (1, 1) & (1, 0) = (1, 0) = M
然后内积可以从元素的位开始,然后......我正在研究如何将它们加在一起。
编辑:
我愚蠢的建议没有考虑到(-1)(-1) = 1
,这是我提出的代表无法处理的。感谢@user92382提出这个问题。
根据您的架构,您可能希望优化临时位向量 - 例如,如果您的代码要编译为FPGA,或布置到ASIC,那么一系列逻辑操作在速度/能量/面积方面将比存储和读取/写入两个大缓冲区更好。
在这种情况下,您可以执行以下操作:
int inner_product(const ternary_vector & a, const ternary_vector & b) {
return __builtin_popcount( a.value & b.value & ~(a.sign ^ b.sign))
- __builtin_popcount( a.value & b.value & (a.sign ^ b.sign));
}
这将很好地布局 - (a.value & b.value & ...)可以启用/禁用XOR门,其输出分成两个有符号的累加器,第一个路径在累积之前被NOT化。
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 计算排序向量的向量中唯一值的计数
- 矩阵向量乘法(cublasDgemv)返回零
- 三元向量的快速内积
- C++向量的三元条件算子
- 在列主顺序中重新排序3D向量三元组是缓慢的
- 成对遍历向量,三元组,