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

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

问题描述

在另一个线程中,有人告诉我 switch 在速度和紧凑性方面可能比 查找表 更好.

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!

感谢您的帮助!

推荐答案

由于我是评论的原作者,我必须添加一个您在问题中没有提到的非常重要的问题.也就是说,原版是关于嵌入式系统的.假设这是一个带有集成闪存的典型裸机系统,与我将重点介绍的 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 缓存.
  • Flash 需要等待状态才能获得更高(即 >ca. 32MHz)的 CPU 时钟.实际比例取决于模具设计、低功耗/高速工艺、工作电压等.
  • 为了隐藏等待状态,Flash 具有比 CPU 总线更宽的读取线.
  • 这只适用于带有指令预取的线性代码.
  • 数据访问会干扰指令预取或在完成前停止.
  • Flash 可能有一个非常小的内部指令缓存.
  • 如果有的话,还有一个更小的数据缓存.
  • 较小的缓存会导致更频繁地丢弃(替换之前已被再次使用的先前条目).

例如STM32F4xx 读取需要 6 个时钟,频率为 150MHz/3.3V,128 位(4 个字).因此,如果需要数据访问,很可能会为所有要获取的数据增加超过 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).

假设紧凑的状态代码,对于实际问题,这对该架构(Cortex-M4)有以下影响:

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

  • 查找表:读取函数地址是一种数据访问.具有上述所有含义.
  • switch otoh 使用特殊的查表"指令,该指令使用指令后面的代码空间数据.所以第一个条目可能已经预取.其他条目不会破坏预取.访问也是代码访问,因此数据进入 Flash 的指令缓存.

还要注意switch不需要函数,因此编译器可以充分优化代码.这对于查找表是不可能的.至少不需要函数进入/退出的代码.

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.

由于上述和其他因素,很难估计.这在很大程度上取决于您的平台和代码结构.但是假设上面给出的系统,切换很可能更快(顺便说一句,更清晰).

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.).

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

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