首页 > 评测 > 评测列表 > MCU

One to Many-多核心编程初探——CY8CKIT-062-BLE评测之二

  • 作者:
  • 来源:21ic
  • [导读]
  • 任务分配与同步是多核编程的最重要问题
  • iMX233-OlinuXino-MICRO
  • MY-iMX6UL开发套件
  • CY3280-CapSense-MBR3
  • PocketBeagle
  • CC3220SF LaunchPad (CC3220SF-LAUNCHXL)
  • Esquilo Air
  • A10-OlinuXino-LIME
  • CY8CKIT-040 PSoC 4000先锋开发套件

image1_copy.jpg

图 任务分配与同步是多核编程的最重要问题

多核心与并行概述

Single core processors are a shrinking minority of all the processors in the world. Multicore processors, offering parallel computing, have displaced single core processors permanently. The future of computing is parallel computing, and the future of programming is parallel programming.

-James Reinders. from Intel

为英文不熟的同学翻译一下子:

单核处理器是处理器世界中正在不断缩减规模的少数群体.多核处理器因为能够提供并行计算,正在永久性地替代单核处理器的地位.未来的计算将是并行计算的天下,未来的编程亦将是并行编程的天下.

因为说这话的人是Intel的工程师,所以嵌入式系统的工程师听起来多多少少可能觉得未免危言耸听了.但是从过去几十年的科技发展经验来看,嵌入式系统的发展总是慢慢会跟随桌面计算,服务器计算的道路,只是稍稍慢那么一拍而已.考虑到硬件的发展速度终将不能以摩尔速度无限制的发展下去,多核与并行的概念引入在嵌入式系统中可能比大多数人预计的要更早一些吧.作者本人也觉得如同OS概念一样,多核与并行的概念在嵌入式系统上与桌面/服务器系统上仅仅只是规模上的差别,不存在本质的区别.

目前而言,作者认为嵌入式系统的多核与桌面/服务器系统的多核有以下显著的差别:

1. 相对而言,嵌入式系统对运算的要求不是那么苛刻,所以数学运算方面的库函数暂时无需特别定制的并行版本;

2. 因为嵌入式系统的多核心多采用big-LITTLE的非对称架构,故此一般有一个核心为主,其余核心都属于从,比较类似于协处理器的概念,但是与FPU等协处理器不同的是这些从核心自主性都很高;

3. 因为上述的big-LITTLE的架构,故此任务的分配上从算法上来讲要简单一些,但是与硬件耦合较为紧密;所以目前桌面/服务器系统上的多核框架如OpenMP,OpenCL还不能简单的搬来利用;

4. 操作系统中的thread概念一般被认为是并行编程的低级别并行,桌面/服务器系统中目前的趋势是抛弃thread这种低级操作,直接使用高级并行框架如OpenMP,Clik Plus等等将整个系统看作一个整体,由框架来分配任务.嵌入式系统对应thread的是各种RTOS的task,这种低等级的并行操作的标准度很低.所以如何将整个嵌入式处理器视作一个整体来隐式进行并行编程可能是最后完成的任务.

我们看一个例子:

 

TIM截图20180123164326.jpg

 

这段代码在桌面计算机中以注释中的命令行build之后运行:

Hello, world.

Hello, world.

Hello, world.

Hello, world.

这是Open MP架构与工具链结合,将受控语句分别分配给四个核心(作者的实验电脑)运行.这个例子如果使用thread来做,创建多个thread,那么移植到嵌入式平台就好办了.但是由于硬件,OS,Library等等的不标准,目前在嵌入式系统的开发中做到如上述代码这样的自动化并行程度.

从上面的例子可以得知,嵌入式系统的并行计算还与桌面/服务器领域的发展趋势还有一大段距离.感兴趣的同学可以去自行了解一下子:Open MP, Open CL, Intel CLik Plus, MPI这几个项目.目前看来嵌入式平台的多核架构类似于操作系统的多个进程.作者还是从这个层面来做一些实验来展示相关的并行概念.

Practice: Mutex-资源互锁

PSoC6的特点是双核心都能同时访问外设与内存.上一集的Demo正是两个内核分别控制LED进行闪烁.那么如果两个内核同时访问同一外设会怎样,比如UART.以下做个实验试验一下子.

首先在上次实验的基础上拖入一个UART来,直接从右边的工具盒子里面拖.

image2.png

图 拖入一个UART

把波特率配置好之后,其余参数都用默认的.

image3.png

图 根据这个把引脚配置

用这个函数试验一下子简单的串口输出是否OK,过程不多讲:

uint32_t Cy_SCB_UART_Put      (CySCB_Type *base, uint32_t data);

确认串口工作之后,重定向STDOUT到串口,也就是要用printf做输出.(其实这实验直接使用底层串口输出函数也可以进行,只是重定向STDOUT这个以后要经常使用,顺带一题.)

因为本系列文章的例子都使用ARM-GCC工具链,故此只需要重写这个函数即可:

int _write(int fd, const void *buffer, size_t count);

(注:PDL中也有Retarget的实现,兼容Keil MDK/IAR/GCC,但是如果只想使用printf,推荐使用本文的简单方法)

详细代码参见作者的git页面.

之后Cortex M0+与Cortx M4以如下的流程运行:

 

  • 本文系21ic原创,未经许可禁止转载!

网友评论