硬件启发循环.废话?

Sti*_*ggo 5 c embedded performance loops verilog

前几天我在Verilog学到了一个很酷的技巧.当你需要反复做某事时.您可以使用移位寄存器来计算增量数.只需将1从LSB移到MSB,当它到达MSB时就完成了.

在C中它将是这样的:

for(j=0b1; !(j & (1<<16)); j=j<<1)
{
/*do a thing 16 times*/
}
Run Code Online (Sandbox Code Playgroud)

我知道它由于位宽而限制使用,但它不涉及任何添加因此它很快.所以我的问题:这有什么用吗?在C语言或任何其他高级语言中使用是否值得?

也许在资源有限的嵌入式系统中.

谢谢

Ole*_*ksi 8

这是非常值得的.它使代码更清晰,更难阅读,性能差异可以忽略不计.

您的编译器可以比您更好地执行这些类型的优化.出于性能原因,这样的短循环甚至可能会展开.但是,如果您编写循环,编译器可能无法轻易解决这个问题,那么您甚至可能会降低程序速度.

这实际上是微优化的一个例子,几乎肯定不会对程序的运行时间产生明显的影响.


Ste*_*fan 5

在我看来,大多数评论/回答的人并不真正理解提问者在谈论什么.Verilog语言用于硬件设计,硬件设计与软件设计完全不同,没有CPU周期或类似的东西.但是,简短的答案仍然是:不.答案很长:

确保换档比添加更简单.对于移位,从FF(触发器)到FF的逻辑要少得多.另外,必须将进位从LSB位传播到MSB位,这意味着log2(N)逻辑电平(N是计数器将达到的最高值).另一方面,移位寄存器将使用N个FF,而加法器仅使用log2(N)FF.所以有一个性能/区域权衡也很大程度上取决于N.一些关于加法器的"独立"信息:http: //en.wikipedia.org/wiki/Adder_%28electronics%29 找不到相似的文章进行移位,但是一旦你理解了加法器,移位器应该是显而易见的.

在RTL中设计状态机时,这可能很重要.但是你提出的代码实际上与上面的代码无关.verilog中的'for'循环意味着所有'工作'将在单个循环中完成.所以实际上会有N个逻辑.此循环与实现无关.它甚至可能只会混淆verilog编译器吐出一些奇怪的东西并影响模拟(其中CPU周期很重要,而且上面的答案都是有效的).有更多工具经验的人可以对此发表评论.


Lun*_*din 1

它不涉及任何添加,所以速度很快

哪种 CPU 架构的移位速度比加法速度更快?另外,是什么让您认为该特定架构的编译器不会自动进行从加法到移位的优化,如果事实证明移位更快?

这个有什么用吗?

出于优化目的,不,它没有任何用处。

是的,出于其他目的,类似的代码通常用于屏蔽字节的各个位。我相信两种最常见的方法是:

uint8_t mask; 

for(mask = 0x01; mask != 0x00; mask<<=1)
{
  do_something (data & mask);
}
Run Code Online (Sandbox Code Playgroud)

或者

for(i=0; i<8; i++)
{
  do_something (data & (1<<i));
}
Run Code Online (Sandbox Code Playgroud)