3

我正在寻找可以处理 8 位实数到复数转换(大小为 65K)的 FFT 引擎。对此的需求是加速实时信号处理引擎。它目前受到 8 位 -> FP32 和 FP32 -> 8 位转换的限制,以及实际的 FFT 受内存带宽限制(我们目前正在使用 FFTW)。

我认为 Spiral 项目可能能够做到这一点http://spiral.net,但他们网页上似乎唯一可用的代码是用于单次或双次转换。

任何人都知道可以做到这一点的任何 C 或 C++ 库吗?

4

2 回答 2

3

有时我遇到了同样的问题。我的数据帧的 FFTW 在 14 毫秒内执行(向前、一些计算和向后),而直接字节(或短)到浮点数组的转换需要 12-19 毫秒。所以我制作了 SSE 函数来将字节转换为浮点数(每个周期 4 个元素),并且获得了显着的速度增益 - 现在转换在 2.2-5 毫秒内完成。

如果您的编译器可以使用自动向量化,请先尝试。

如果没有,请使用内在函数编写简单的转换函数。

我使用过内联汇编程序(MOVD、PUNPCKLBW、PUNPCKLWD、CVTDQ2PS、MOVAPS 命令序列)。

procedure BytesToSingles(Src, Dst: Pointer; Count: Integer);
asm
  //EAX = Src pointer to byte array
  //EDX = Dst pointer to float array !!! 16 byte-aligned !!!
  //ECX = Count (multiple of four)
  SHR ECX, 2           // 4 elements per cycle
  JZ @@Exit
  PXOR XMM7, XMM7      // zeros
@@Cycle:
  MOVD XMM1, [EAX]     // load 4 bytes
  PUNPCKLBW XMM1, XMM7 // unpack to words
  PUNPCKLWD XMM1, XMM7 // words to int32
  CVTDQ2PS XMM0, XMM1  // convert integers to 4 floats
  MOVAPS [EDX], XMM0   // store 4 floats to destination array
  ADD EAX, 4           // move array pointers
  ADD EDX, 16
  LOOP @@Cycle
@@Exit:
end;

请注意,正如 Paul R 在评论中所写,对 8 位数据的 FFT 实现会遇到数值错误问题。

于 2013-04-18T03:46:18.310 回答
2

不想在定点进行所有处理。您的数据将在该大小的 FFT 中变成糊状。从技术上讲,您可以使用 32 位定点并保留所有动态,但您仍然必须转换数据,并且它会比使用浮点数慢(您标记了 SSE,所以我假设您在具有 FPU 的英特尔机器上) . 我的意见基于我创建Kissfft的工作

而是专注于加快类型转换。我没有运行 MBo 的汇编代码,但它看起来是正确的方法。我认为展开可能会使其更快。

如果您不习惯汇编,请改用 SSE2 编译器内部函数。它会一样快(假设编译器不错),它会让你的代码更具可读性和可维护性。 这个答案会给你大部分你需要的东西。

于 2013-04-18T13:32:46.723 回答