在GCD中并发访问单个FFTSetup数据结构

时间:2012-07-07 20:00:34

标签: objective-c ios multithreading grand-central-dispatch accelerate-framework

是否可以创建 FFTSetup数据结构并使用它同时执行多个FFT计算?会有类似以下的工作吗?

FFTSetup fftSetup = vDSP_create_fftsetup(
                                         16,         // vDSP_Length __vDSP_log2n,
                                         kFFTRadix2  // FFTRadix __vDSP_radix
                                         );
NSAssert(fftSetup != NULL, @"vDSP_create_fftsetup() failed to allocate storage");

for (int i = 0; i < 100; i++)
{
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
  ^{
    vDSP_fft_zrip(
                  fftSetup,              // FFTSetup __vDSP_setup,
                  &(splitComplex[i]),    // DSPSplitComplex *__vDSP_ioData,
                  1,                     // vDSP_Stride __vDSP_stride,
                  16,                    // vDSP_Length __vDSP_log2n,
                  kFFTDirection_Forward  // FFTDirection __vDSP_direction
                  );
  });
}

我认为答案取决于以下考虑因素:

1)vDSP_fft_zrip()仅以“只读”的方式访问fftSetup中的数据(或其指向的数据)吗?或者fftSetup中是否有一些临时缓冲区(临时空间)由vDSP_fft_zrip()在执行其FFT计算时写入?

2)如果以“只读”的方式访问fftSetup 中的数据,那么多个进程/线程/任务/块是否可以同时访问它? (我正在考虑这样一种情况:多个进程可以打开同一个文件进行阅读,但不一定是写作或附加。这类比是否合适?)

在相关的说明中,FFTSetup数据结构占用了多少内存?有没有办法找出来? (这是一种不透明的数据类型。)

3 个答案:

答案 0 :(得分:6)

您可以创建一个FFT设置并重复并同时使用它。这是预期用途。 (我是vDSP当前vDSP_fft_zrip实现和其他FFT实现的作者。)

答案 1 :(得分:2)

Using Fourier Transforms中,我们被告知FFTSetup包含FFT权重数组,这是一系列复数指数。 vDSP_create_fftsetup documentation

  

准备好后,可以通过FFT重复使用设置结构   函数(读取结构中的数据但不改变它)   对于任何(2的幂)长度,直到您创建时指定的长度   结构。

所以

  1. 从概念上讲,vDSP_fft_zrip不需要修改权重数组,因此它似乎是一个不会改变FFTSetup的FFT函数(我还没有看到任何除了创建/销毁之外),但是不能保证实际的实现方式 - 它可以做任何事情。

  2. 如果 vDSP_fft_zrip以只读方式真正访问其FFTSetup,则可以从多个线程中执行此操作。

  3. 对于内存使用情况,对于k = [0..N-1],FFT权重数组为e ^ {i * k * 2 * M_PI / N},它们是N个复数浮点值,因此将为2 * N *的sizeof(浮点)。

    但是那些复杂的指数是非常对称的,所以谁知道,实施可能需要更少的内存。或者更多!

    在你的情况下,N = 2 ^ 16,所以看到最多使用256k并不奇怪。

    离开你的地方?我认为可以从多个线程访问FFTSetup似乎是合理的,但它似乎没有文档记录。你可能很幸运。或者现在或在未来版本的框架中不幸和令人不快地感到惊讶。

    所以...你感到幸运吗?

答案 2 :(得分:0)

我不会尝试与vDSP函数或Accelerate框架中的任何其他函数(其中vDSP是其中的一部分)的任何显式并发。为什么?因为Accelerate已经设计为代表您利用多个内核以及给定处理器实现的特定细微差别 - 请参阅http://developer.apple.com/library/mac/#DOCUMENTATION/Darwin/Reference/ManPages/man7/vecLib.7.html。您最终可能会重新并行化已实现的内部并行计算(如果不是现在,则可能在更高版本中)。加速框架的最佳方法通常是假设它比您更聪明,并以最简单的方式使用它,然后进行性能测量。如果这些测量结果反映出某种程度的性能不足以满足您的需求,那么请尝试自己的优化(和/或在http://bugreport.apple.com提交针对Accelerate框架的错误报告,因为该框架的作者总是对知道感兴趣他们的努力在某种程度上是否达不到开发人员的要求。)