我有一个16位的值,其位“隔行扫描”。
我想获得一个包含8个项目(值0到3)的数组,按以下顺序存储这些位:
这是一个简单的解决方案:
function uninterlace(n) {
return [((n>>7)&1)|((n>>14)&2), // bits 7 and 15
((n>>6)&1)|((n>>13)&2), // bits 6 and 14
((n>>5)&1)|((n>>12)&2), // bits 5 and 13
((n>>4)&1)|((n>>11)&2), // bits 4 and 12
((n>>3)&1)|((n>>10)&2), // bits 3 and 11
((n>>2)&1)|((n>> 9)&2), // bits 2 and 10
((n>>1)&1)|((n>> 8)&2), // bits 1 and 9
((n>>0)&1)|((n>> 7)&2)];// bits 0 and 8
}
有谁知道更好(更快)的方式吗?
修改
注意:
答案 0 :(得分:1)
比手写的展开循环更快?我对此表示怀疑。
使用for
循环可以减少重复代码,但这不会让它运行得更快。
答案 1 :(得分:1)
def uninterlace(n) {
mask = 0x0101 // 0b0000_0001_0000_0001
slide = 0x7f // 0b0111_1111
return [(((n >> 0) & mask) + slide) >> 7,
(((n >> 1) & mask) + slide) >> 7,
(((n >> 2) & mask) + slide) >> 7,
(((n >> 3) & mask) + slide) >> 7,
(((n >> 4) & mask) + slide) >> 7,
(((n >> 5) & mask) + slide) >> 7,
(((n >> 6) & mask) + slide) >> 7,
(((n >> 7) & mask) + slide) >> 7]
}
每个条目只有4个操作,而不是5个。诀窍在于重用移位的值。 slide
的相加使相关位相互移动,并且移位7使它们处于低位。使用+
可能是一个弱点。
更大的弱点可能是每个条目的操作必须完全按顺序完成,从进入处理器的管道到离开它时会产生4条指令的延迟。这些可以完全流水线化,但仍会有一些延迟。该问题的版本暴露了一些指令级并行性,并且在给定足够的执行资源的情况下,每个条目可能只有3个指令的延迟。
有可能将多个提取组合成更少的操作,但我还没有看到这样做的方法。事实上,隔行扫描确实具有挑战性。
编辑:对称地处理低位和高位的两遍方法,使用交错的0,将它们彼此相移一个,或者结果可以更快,并且可以扩展到更长的位串。
根据佩德罗的评论修改slide
。很抱歉花时间学习我糟糕的基础转换技巧。它最初是0xef
,它将0位置于错误的位置。
答案 2 :(得分:1)
好的,现在每个项目有3个操作(测试和工作)。
这是Novelocrat答案的变体。它使用可变掩模和幻灯片。
function uninterlace(n) {
return [((n & 0x8080) + 0x3FFF) >> 14,
((n & 0x4040) + 0x1FFF) >> 13,
((n & 0x2020) + 0x0FFF) >> 12,
((n & 0x1010) + 0x07FF) >> 11,
((n & 0x0808) + 0x03FF) >> 10,
((n & 0x0404) + 0x01FF) >> 9,
((n & 0x0202) + 0x00FF) >> 8,
((n & 0x0101) + 0x007F) >> 7];
}
答案 3 :(得分:0)
如果一个小的预先计算的128个条目的表乘以2?
int[128] b1 = { 2, 3, 3, .. 3};
int[128] b0 = { 0, 1, 1, .. 1};
function uninterlace(n) {
return [(n & 0x8000) ? b1 : b0)[n & 0x80],
(n & 0x4000) ? b1 : b0)[n & 0x40],
(n & 0x2000) ? b1 : b0)[n & 0x20],
(n & 0x1000) ? b1 : b0)[n & 0x10],
(n & 0x0800) ? b1 : b0)[n & 0x08],
(n & 0x0400) ? b1 : b0)[n & 0x04],
(n & 0x0200) ? b1 : b0)[n & 0x02],
(n & 0x0100) ? b1 : b0)[n & 0x01]
];
}
这使用位掩码和表查找而不是移位和添加,并且可能更快。