正文
我们来看一看下面的示意图,以更好地了解协处理器如何与微处理器(CPU)或通用处理器的协同工作。
数字沿彩色线移动。输入/输出可以是协处理器、鼠标、键盘以及其他设备。
我们可以将绿色和浅蓝色的公共总线视为管道。数字通过这些管道推送到 CPU 的不同功能单元(图中为灰色盒子)。这些盒子的输入和输出连接到了管道。
你可以认为每个盒子的输入和输出都带有阀门。红色控制线可用于打开和关闭这些阀门。因此,负责红线的解码器(Decoder)可以打开两个灰色盒子上的阀门,让数字在它们之间流动。
图:你可以将数据总线视为管道,而红色控制线则负责打开和关闭阀门。
但是,在电子设备中,这是通过我们所谓的多路复用器完成的,而不是实际的阀门。
如果想执行数字运算,则首先需要将数字放入寄存器中。解码器使用控制线打开灰色盒子“内存”和“寄存器”之间的阀门。具体操作为:
-
解码器打开负载存储单元(LSU)上的阀门,内存地址从绿色地址总线上流出。
-
打开内存盒上的阀门,这样它就可以接收地址了,而地址由绿色管道(地址总线)负责传送。所有其他阀门都关闭,这样输入/输出就无法接收地址。
-
选中地址指定的内存单元。然后解码器会打开通往数据总线的阀门,这样选定内存单元的内容就会流出到蓝色数据总线上。
-
内存单元的数据可以流到任何地方,但是解码器仅打开了寄存器的输入阀门。
鼠标、键盘、显示器、GPU、FPU、神经引擎和其他协处理器都是“输入/输出”盒子。访问方式与访问内存一样。硬盘驱动器、鼠标、键盘、网卡、GPU、DMA(直接内存访问)和协处理器都被映射到自己的内存地址。
举个例子,如果处理器尝试从内存地址 84 读取数据:鼠标的 x 坐标,而 85 代表鼠标的 y 坐标。
因此,为了获取鼠标坐标,你可以通过汇编代码中执行以下操作:
load r1, 84 ; get x-coordinate
loar r2, 85 ; get y-coordinate
对于 DMA 控制器,可能地址 110、111 和 113 有特殊的含义。下面这些伪汇编代码可以使用这些地址与 DMA 控制器进行交互:
loadi r1, 1024 ; set register r to source address
loadi r2, 50 ; bytes to copy
loadi r3, 2048 ; destination address
store r1, 110 ; tell DMA controller start address
store r2, 111 ; tell DMA to copy 50 bytes
store r3, 113 ; tell DMA where to copy 50 bytes to
当然,一般软件开发人员不需要知道这些,这些工作都是由设备驱动程序完成的。你使用的程序无法真正看到这些不可见的虚拟内存地址。但是,驱动程序会将这些地址映射到其虚拟内存地址。
本质上,我们拿到的是真实的地址。绿色总线上的地址将从虚拟地址转换为实际物理地址。当我在 DOS 中编写 C/C++的程序时,就不会遇到这种情况。我可以将 C 指针直接指向视频的内存地址,然后直接修改图片。
char *video_buffer = 0xB8000; // set pointer to CGA video buffer
video_buffer[3] = 42; // change color of 4th pixel
协处理器的工作方式与此相同。神经引擎、GPU、安全协处理器(Secure Enclave)都拥有可以与之通信的地址。你需要了解这些,同时也需要了解 DMA 控制器可以异步工作。
这意味着
CPU 可以为神经引擎或 GPU 安排一整套指令,并将它们写入内存的缓冲区。
然后,通过与 IO 地址的对话,将这些指令的位置通知给神经引擎或 GPU 协处理器。
你肯定不希望 CPU 处于空闲状态,等待协处理器仔细检查所有指令和数据。你也不想让 DMA 遇到这种情况。这就是为什么一般我们都需要使用某种中断的原因。