确定 MIPS 中数字的位表示的奇偶校验
Posted
技术标签:
【中文标题】确定 MIPS 中数字的位表示的奇偶校验【英文标题】:determine parity of a bit representation of a number in MIPS 【发布时间】:2010-04-11 15:17:18 【问题描述】:MIPS 中是否有一些指令可以确定某个位表示的奇偶校验?我知道确定“数字”是否具有偶校验或奇校验是将二进制表示的各个位异或在一起,但这对于一组 MIPS 指令来说似乎是计算密集型的......我需要这样做尽快。
另外,我正在处理的数字是用格雷码表示的......只是把它扔在那里。那么 MIPS 中是否有一些伪指令来确定“数字”的奇偶性,还是我必须手动完成?
如果没有 MIPS 指令(这似乎不太可能),有什么建议可以手动完成吗?
谢谢, 赫里斯托
跟进:我发现了一个优化,但我的实现不起作用。
unsigned int v; // 32-bit word
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x11111111U) * 0x11111111U;
return (v >> 28) & 1;
【问题讨论】:
【参考方案1】:我不知道有任何带有奇偶校验指令的 MIPS 变体,但是有一个比依次运行每个 32 位的明显方法更快地计算奇偶校验的技巧。在 C 中:
result = in ^ (in >> 16);
result ^= (result >> 8);
result ^= (result >> 4);
result ^= (result >> 2);
result ^= (result >> 1);
result &= 1;
在第一步之后,结果的低 16 位包含输入的第 N 位和 N+16 位的奇偶校验 - 本质上,奇偶校验计算已经一次执行了 16 步。写resultN
表示“result
的第 N 位”:
result0 = in0 ^ in16
result1 = in1 ^ in17
result2 = in2 ^ in18
...
result7 = in7 ^ in23
result8 = in8 ^ in24
...
result15 = in15 ^ in31
(现在可以忽略result
的剩余前 16 位;它们在剩余的计算中没有用处)。
经过第二步,result
的低8位包含原始输入的N、N+8、N+16、N+24位的奇偶校验:
result0 = result0 ^ result8 = in0 ^ in8 ^ in16 ^ in24
result1 = result1 ^ result9 = in1 ^ in9 ^ in17 ^ in25
...
result7 = result7 ^ result15 = in7 ^ in15 ^ in23 ^ in31
(同样,从这里开始可以忽略剩余的位)。
...以此类推,直到原始输入的所有位的奇偶校验最终到达result
的底部位:
result0 = in0 ^ in1 ^ in2 ^ ... ^ in30 ^ in31
这很容易直接翻译成 MIPS 汇编;这是 11 条指令:
# input in $a0, output in $v0, $t0 corrupted
srl $t0, $a0, 16
xor $v0, $a0, $t0
srl $t0, $v0, 8
xor $v0, $v0, $t0
srl $t0, $v0, 4
xor $v0, $v0, $t0
srl $t0, $v0, 2
xor $v0, $v0, $t0
srl $t0, $v0, 1
xor $v0, $v0, $t0
and $v0, $v0, 1
可能的改进可能是使用查找表。例如,在前两个步骤之后,我们有:
result0 = in0 ^ in8 ^ in16 ^ in24
result1 = in1 ^ in9 ^ in17 ^ in25
...
result7 = in7 ^ in15 ^ in23 ^ in31
所以此时我们可以使用 256 字节的查找表。在 C 中:
result = in ^ (in >> 16);
result ^= (result >> 8);
result = lookup_table[result & 0xff];
lookup_table[n]
已预先计算的位置,例如:
for (i = 0; i < 256; i++)
n = i ^ (i >> 4);
n ^= (n >> 2);
n ^= (n >> 1);
lookup_table[i] = n & 1;
这是 7 个 MIPS 指令,不包括将查找表基地址加载到寄存器中:
# input in $a0, lookup table address in $a1, output in $v0, $t0 corrupted
srl $t0, $a0, 16
xor $v0, $a0, $t0
srl $t0, $v0, 8
xor $v0, $v0, $t0
andi $v0, $v0, 0xff
addu $t0, $a1, $v0
lbu $v0, 0($t0)
但是,这是 7 条指令,其中包括内存访问,而 11 条指令是纯粹的寄存器操作;它可能会也可能不会更快。 (这种微优化总是需要分析!)
【讨论】:
感谢您的回复。这就是我目前拥有的......但我正在尝试将代码优化为更少的指令,因为这组指令将被多次调用并且它会降低性能。有什么优化想法吗? 第二个xor
之后,所有有用的信息都在后8位;最终的答案只是这些位的函数,因此您可以在那时将它们用作 256 字节查找表的索引。这是否会更快取决于内存访问、缓存等的速度 - 你必须尝试并分析它......
“所有有用的信息都在底部 8 位”是什么意思?所以你建议移位 16、异或、移位 8、异或,然后最右边的 8 位是重要的?
好的。非常感谢!我已经实现了这个并且它不起作用,但我确定我有一些我看不到的错误。
@Hristo:哎呀,不,这将是我搞砸查找表初始化的错。我现在已经更正了。对此感到抱歉。以上是关于确定 MIPS 中数字的位表示的奇偶校验的主要内容,如果未能解决你的问题,请参考以下文章