双核 ARMv7 处理器中的并行处理

3
我正在使用包含双核 ARM A9 处理器并运行 Linux 的 Zedboard。该板与外部 I/O 设备通信。
我有两个用 C 语言编写的函数,必须并行运行。
一个函数调用 while 循环并连续将数据转储到外部设备,并将处理后的数据接收回内存指针。
另一个函数从指针位置读取数据,创建副本并进行计算密集型处理(如 FFT、信号对齐等,速度较慢)。
外部设备需要每秒 1500 万个样本的数据。如果只运行第一个函数,则能够实现这一要求,且占用一个 ARM 核心的约 70%。当同时运行这两个函数时,两个 ARM 核心都达到极限,发现无法以所需的样本速度向外部设备提供数据。
是否有一种方法可以将这两个函数限制在独立的核心中(第二个函数速度较慢无所谓,但第一个函数的性能不能受到影响),并仍然能够在它们之间共享数据?
我尝试使用 OpenMP,但无法实现所需的性能。我阅读了关于 SCHED_SETAFFINITY 的资料,但在理解其实现方面遇到了问题。
我已经尽可能地使用 NEON 构造/库和 ARM 处理器的自动向量化功能对每个函数进行了优化。

你可能是受到内存或缓存的限制。在fft线程中插入一些无操作指令。 - rustyx
你是否尝试过调整线程的优先级,以确定哪些函数应该运行? - DawidPi
FFT的大小和输入/输出类型是什么?你确定你正在使用最好的算法和库吗?你在做SDR吗?无论如何,我在网上看到了很多糟糕的NEON实现,它们根本无法使用。 - Jake 'Alquimista' LEE
是的,我正在进行SDR实现的工作。我使用2048的FFT大小。由于我的输入和输出类型具有复杂性质,因此我使用两个float32数组来存储输入和输出,这些数组在传输和接收之前被强制转换为int16以进行ADC / DAC。我正在使用Project Ne10库进行信号处理实现。 - Sushant S Samuel
1个回答

3
您可以使用以下命令将每个单独的线程设置到不同的核心上:
 int sched_setaffinity(pid_t pid,size_t cpusetsize,cpu_set_t *mask);

从手册中得知: 一个进程的CPU亲和力掩码决定了它可以运行的CPU集合。在多处理器系统上,设置CPU亲和力掩码可以用于获得性能优势。例如,通过将一个CPU专用于一个特定的进程(即将该进程的亲和力掩码设置为指定单个CPU,并将所有其他进程的亲和力掩码设置为排除该CPU),可以确保该进程的最大执行速度。将进程限制为在单个CPU上运行还可以避免在进程停止在一个CPU上执行,然后重新开始在不同CPU上执行时造成的缓存失效所带来的性能成本。
但是,如果您的代码在输入和输出线程之间具有硬数据关系,则多线程可能比单核使用更慢!这与内存/缓存尤其是在arm的所有核/内存/缓存和外部总线系统之间几乎没有关系。您应该调整优先级、亲和力和可能的其他参数。
顺便说一句:1 GHZ Arm上的Linux并行FFT I/O达到每秒15百万个样本。哇!热门的东西;)

好的,先生。我会尝试设置线程优先级,并向您汇报结果。 - Sushant S Samuel
我猜他正在处理SDR(软件定义无线电),鉴于数据大小和要求。每秒15M个样本并不多。 - Jake 'Alquimista' LEE
是的,先生,15.36MSps是我必须要达到的最基本要求,我最终需要将其提高到61.44MSps,但问题在于Zedboard中Arm处理器的处理能力。 - Sushant S Samuel
先生,即使将函数限制在它们各自独立的核心中,我仍然无法达到性能,可能是因为600MHz双Arm A9处理器。但是,我现在已经更改了系统,并使用另一个处理器来共享高计算任务,通过以太网连接。 - Sushant S Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接