查找表VS用C嵌入式软件开关 [英] Lookup table vs switch in C embedded software

查看:215
本文介绍了查找表VS用C嵌入式软件开关的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在另一个线程,有人告诉我,一个开关可能比在速度和紧凑性方面具有的查找表的更好。

In another thread, I was told that a switch may be better than a lookup table in terms of speed and compactness.

所以我想明白这之间的区别:

So I'd like to understand the differences between this:

static void func1(){}
static void func2(){}

typedef enum
{
    FUNC1,
    FUNC2,
    FUNC_COUNT
} state_e;

typedef void (*func_t)(void);

const func_t lookUpTable[FUNC_COUNT] =
{
    [FUNC1] = &func1,
    [FUNC2] = &func2
};

void fsm(state_e state)
{
    if (state < FUNC_COUNT) 
        lookUpTable[state]();
    else
        ;// Error handling
}

和这样的:

static void func1(){}
static void func2(){}

void fsm(int state)
{
    switch(state)
    {
        case FUNC1: func1(); break;
        case FUNC2: func2(); break;
        default:    ;// Error handling
    }
}

我认为一个查找表是更快,因为编译器尝试在可能的时候switch语句转换成跳转表。
由于这可能是错误的,我想知道为什么!

I thought that a lookup table was faster since compilers try to transform switch statements into jump tables when possible. Since this may be wrong, I'd like to know why!

感谢您的帮助!

推荐答案

由于我是注释的原作者,我要补充你没有在你的问题提到一个非常重要的问题。也就是说,原来为约嵌入式系统。 presuming这是一个典型的裸机系统集成闪存,也有从PC上,我将集中非常重要的区别。

As I was the original author of the comment, I have to add a very important issue you did not mention in your question. That is, the original was about an embedded system. Presuming this is a typical bare-metal system with integrated Flash, there are very important differences from a PC on which I will concentrate.

这样的嵌入式系统通常具有以下限制。

Such embedded systems typically have the following constraints.


  • 没有CPU缓存。

  • 闪存需要更高(即> CA。32MHz的)CPU时钟等待状态。实际比例取决于模具设计,低功率/高速处理,工作电压等

  • 要隐藏等待状态,Flash有更广泛的读线比CPU总线。

  • 这只是非常适用于线性code与指令prefetch。

  • 数据访问打扰指令prefetch或者被延迟,直到它完成。

  • 闪存可能有一个内部非常小的指令缓存。

  • 如果任何可言,还有一个更小的数据缓存。

  • 小缓存导致更频繁的捣毁(更换previous条目已被使用的另一种时间之前)。

有关如在STM32F4xx读需要6个时钟在128位(4个字)为150MHz / 3.3V。因此,如果需要的数据访问,有很好的机会它增加了超过12个时钟延迟对所有数据要读取(也有涉及额外的周期)。

For e.g. the STM32F4xx a read takes 6 clocks at 150MHz/3.3V for 128 bits (4 words). So if a data-access is required, chances are good it adds more than 12 clocks delay for all data to be fetched (there are additional cycles involved).

presuming紧凑的语句codeS,对于实际的问题,这已经在此架构下的效果(的Cortex-M4):

Presuming compact state-codes, for the actual problem, this has the following effects on this architecture (Cortex-M4):


  • 查找表:读取函数地址是一个数据访问。上面提到的所有问题。

  • 交换机OTOH使用它使用code空间数据权指令后面一个特殊的表查找指令。所以第一项是可能已经prefetched。其他条目不破prefetch。同时存取为code-存取权限,因此数据进入闪存的指令缓存。

另外请注意,开关不需要的功能,从而使编译器可以充分优化code。这是不可能的一个查找表。至少code的函数入口/不需要退出。

Also note that the switch does not need functions, thus the compiler can fully optimise the code. This is not possible for a lookup table. At least code for function entry/exit is not required.

由于上述及其他因素的影响,估计很难说。这在很大程度上取决于你的平台和code结构上。不过,假设上面给出的系统中,开关很可能更快(更清晰,顺便说一句)。

Due to the aforementioned and other factors, an estimate is hard to tell. It heavily depends on your platform and the code structure. But assuming the system given above, the switch is very likely faster (and clearer, btw.).

这篇关于查找表VS用C嵌入式软件开关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆