Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在内存阵列中拾取一对位(0b11)_C_Count_Bit - Fatal编程技术网

C 在内存阵列中拾取一对位(0b11)

C 在内存阵列中拾取一对位(0b11),c,count,bit,C,Count,Bit,我的嵌入式系统具有128KB的内存阵列结构,用于特定用途 每个2比特代表4状态(状态0、状态1、状态2、状态3) 我想计算内存阵列中的总状态3(0b11) 例如0xFF001234=1111111 0000 0001 0010 0011 0100 它计数为5(0b11) 我搜索了算法,但它只计算单个位 - 我希望避免像每隔2比特比较0b11这样的贪婪算法 有人有好主意吗 ps:我使用的是LEON3 Sparc V8 32位处理器,使用C语言你有一个数组uint32_t states[],其中每个

我的嵌入式系统具有128KB的内存阵列结构,用于特定用途

每个2比特代表4状态(状态0、状态1、状态2、状态3)

我想计算内存阵列中的总状态3(0b11)

例如0xFF001234=1111111 0000 0001 0010 0011 0100

它计数为5(0b11)

我搜索了算法,但它只计算单个位 -

我希望避免像每隔2比特比较0b11这样的贪婪算法

有人有好主意吗


ps:我使用的是LEON3 Sparc V8 32位处理器,使用C语言

你有一个数组
uint32_t states[]
,其中每个
状态[I]
代表16个状态

要计算变量
uint32\t s
中的
0b11
状态数,可以使用以下方法:

首先,预处理
s
,使每个状态
0b11
只产生一个
1
位,所有其他状态产生
0
位。然后计算
1
位的数量

预处理 将
s
拆分为每个状态的左位
l
和右位
r

s AB CD EF GH IJ LM无PQ RS TU VW XY ZΓΔ∏ΦψБЖ
l=s&0xAAAAAA=A0 C0 E0 G0 I0 L0 N0 P0 R0 T0 V0 X0 Z0Δ0Φ0Б0
r=s&0x555555=0B 0D 0F 0H 0J 0O 0Q 0S 0U 0W 0Y 0Γ0∏0ψ0Ж
然后对齐
l
r
的位

(l>>>1)=0A 0C 0E 0G 0I 0L 0N 0P 0R 0T 0V 0X 0Z 0Δ0Φ0Б
r=0B 0D 0F 0H 0J 0O 0Q 0U 0W 0Y 0Γ0∏0ψ0Ж
最后,当且仅当状态为
0b11
时,使用
&
获取
1
-位

(l>>>1)&r=0?0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0? 0?
如果相应的状态为
0b11
0
,则此处
1

同样的结果也可以通过简化公式
(s>>>1)和s&0x555555
实现

位计数 要计算
s
中的
0b11
状态,我们只需计算
1
-位
(s>>>1)&s&0x5555

如本书或本文所述,位计数可以在没有循环的情况下完成

此处显示的方法仅适用于单个数组元素。计算整个数组循环中元素的状态

优化
正如Lundin在评论中指出的那样,如果您的处理器无法将
uint32\t
装入寄存器,那么操作
(s>>>1)
可能会很昂贵。在这种情况下,明智的做法是将数组
状态[]
声明为
uint32\u t
,但在处理器上效果最好的程序都是一样的,您只需或多或少地使用
555…
。如果由于某种原因您无法更改数组的类型,您仍然可以像访问其他类型的数组一样访问它,请参见。

您使用的是什么编程语言以及如何访问内存?对不起,我使用的是C语言,如果您的“内存数组结构”是什么类型?它只是4字节内存的数组处理器真的每4位访问内存4位吗?听起来很奇怪。这在<32位的低端CPU上非常无效。在没有特定目标的情况下,不可能向最优算法提出建议。我认为它是有效的(无论它有多快/慢)。关于效率:我想即使在这样的CPU上,这种方法仍然比循环快,所以不会那么糟糕。无论如何,现在考虑这样的事情对我来说似乎是过早的优化——OP要求“避免[…]每2位比较0b11”,就是这样。在8位MCU上移动32位整数比在字节数组上迭代慢约100倍。这不是过早的优化,而是相反的:现实世界的优化。
~100倍慢
–好吧,我没想到这意味着在软件中实现的移位
>>1
(通过移位和组合单个字节)会比硬件移位快得多。我给这个答案增加了一些提示。谢谢你的评论。@Socowi最好从简单的方法开始
if((arr[idx]&0x03)==0x03)count++(与0x0c、0x30、0xc0相同)。任何合适的编译器都会看到dat
arr[idx]
被使用了四次,并将其保存在循环体的寄存器中。(指针版本相同)。此外,循环最多只需要三个变量,它们都可以保存在寄存器中。