埋め込み式C関数の最適化
7102 ワード
0.はじめに
これは単純な関数の最適化であるが,コードの読みやすさと効率の総合的な考慮を体現している.
優秀なコードを書く方法を聞かれたら、「もう1版書く」と答えた.
1.バージョン1
リングbufferからデータを取り出し、構造体に配置します.bufferのデータはバイト毎に記憶するが、構造体の各セルデータはint 16である.
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.まとめ
インタフェースを変更しない場合は,関数の読みやすさと効率をできるだけ高め,コード産出効率と品質のバランスを徐々に把握する.止まらないで、次の版はもっといいです.