嵌入式C函数优化

Posted 啊哈彭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式C函数优化相关的知识,希望对你有一定的参考价值。

0. 引言

  这是一个简单函数的优化,但却体现了代码易读性和效率的综合考虑。

  如果问我如何写出优秀的代码,答曰:再写一版。

1. 版本1

  从环形buffer中取出数据,然后放到一个结构体中。buffer中的数据是按字节存储,但是结构体的每个单元数据是int16.

void GetDataFromMeas(int8_t *rawDataBuf, fftStruct *fftBufVx)
 {
    int8_t *src_ptr = rawDataBuf;  // pointer to raw data buffer.
    uint32_t i=0;
    int16_t volt[4] = {0,0,0,0};
 
    for(i = 0; i< LEN_NUM; i++)
    {
        volt[0] = *(int16_t *)src_ptr; // UL1
        src_ptr++;
        src_ptr++;
        volt[1] = *(int16_t *)src_ptr; // UL2
        src_ptr++;
        src_ptr++;
        volt[2] = *(int16_t *)src_ptr; // UL3
        src_ptr++;
        src_ptr++;
        volt[3] = *(int16_t *)src_ptr; // ULN
        src_ptr++;
        src_ptr++;
        *(fftBufVx->nL1_r + i) = (float32_t)(volt[0]-volt[3]);
        *(fftBufVx->nL1_i + i) = 0;
        *(fftBufVx->nL2_r + i) = (float32_t)(volt[1]-volt[3]);
        *(fftBufVx->nL2_i + i) = 0;
        *(fftBufVx->nL3_r + i) = (float32_t)(volt[2]-volt[3]);
        *(fftBufVx->nL3_i + i) = 0;
     }
 }

2. 版本2

  上一版怎么看都啰啰嗦嗦,先把数据按照字节取出来,然后拼成16位的再放入到临时数组,最后按照顺序写入到接收结构体数组里。

  既然数据是16位的,那么为什么还要先按照8位取出来在拼接呢,多此一举。

  修改后,代码行数锐减,结构更加清晰。

void GetDataFromMeas(int8_t *rawDataBuf, fftStruct *fftBufVx)
 {
    int16_t *src_ptr = (int16_t *)rawDataBuf;  // pointer to raw data buffer.
    uint32_t i=0;
    for(i = 0; i< LEN_NUM; i++)
    {
        *(fftBufVx->nL1_r + i) = (float32_t)(src_ptr[0]-src_ptr[3]); // UL1
        *(fftBufVx->nL1_i + i) = 0;
        *(fftBufVx->nL2_r + i) = (float32_t)(src_ptr[1]-src_ptr[3]); // UL2
        *(fftBufVx->nL2_i + i) = 0;
        *(fftBufVx->nL3_r + i) = (float32_t)(src_ptr[2]-src_ptr[3]); // UL3
        *(fftBufVx->nL3_i + i) = 0;
        
        src_ptr = src_ptr + 4;
     }
 }

3. 版本3

  指针加偏移与数组下标其实本质都是一个东西,数据量是如此之大,可以考虑省下计算地址偏移的操作,直接引用数组的下标。

void GetDataFromMeas(int8_t *rawDataBuf, fftStruct *fftBufVx)
 {
    int16_t *src_ptr = (int16_t *)rawDataBuf;  // pointer to raw data buffer.
    uint32_t i=0;
    for(i = 0; i< LEN_NUM; i++)
    {
        fftBufVx->nL1_r[i] = (float32_t)(src_ptr[0]-src_ptr[3]); // UL1
        fftBufVx->nL1_i[i] = 0;
        fftBufVx->nL2_r[i] = (float32_t)(src_ptr[1]-src_ptr[3]); // UL2
        fftBufVx->nL2_i[i] = 0;
        fftBufVx->nL3_r[i] = (float32_t)(src_ptr[2]-src_ptr[3]); // UL3
        fftBufVx->nL3_i[i] = 0;

        src_ptr = src_ptr + 4
     }
 }

4. 总结

  再不改变接口的情况下,尽量提高函数的易读性与效率。永不止步,下一版更好。

以上是关于嵌入式C函数优化的主要内容,如果未能解决你的问题,请参考以下文章

《安富莱嵌入式周报》第279期:强劲的代码片段搜索工具,卡内基梅隆大学安全可靠C编码标准,Nordic发布双频WiFi6 nRF7002芯片

嵌入式C代码的十种优化方案

MDK中嵌入汇编方法

浅析嵌入式C优化技巧

如何有条件地将 C 代码片段编译到我的 Perl 模块?

如何在C或C++代码中嵌入ARM汇编代码