我有两个CPU在芯片上,他们有一个共享内存。 这不是一个SMP体系结构。 芯片上只有两个CPU共享内存。
第一个CPU上有一个类Unix操作系统,第二个CPU上有一个Linux操作系统。
第一个CPU做一些工作,这个工作的结果是一些数据。 第一个CPU完成工作后,应该向另一个CPU说,工作完成,第二个CPU必须处理这些数据。
处理处理器间通信的方式是什么? 我应该用什么algorithm来做到这一点?
任何参考文章关于它将不胜感激。
这一切都取决于硬件。 如果你所拥有的只是共享内存,而没有其他的通信方式,那么你必须使用某种类型的轮询。
你的两个处理器都在运行linux吗? 他们如何处理共享内存? 一个好的解决方案是使用链表作为fifo。 在这个fifo你把数据描述符,如地址和大小。
例如,你可以有一个输入和输出先进先出,如下所示:
循环
处理器B等待输出FIFO中的数据描述符
当然,最难的部分就是锁定。 可能是你应该重新提出你的问题来强调这不是'标准'的SMP。
如果你没有原子测试和设置位操作在内存中,我想你必须采取一个方案,其中一些内存区域只能写入一个处理器,而另一个只能读取。
编辑:请参阅Hasturkun回答,从一个处理器到另一个处理器的消息传递方式,使用有序写入而不是原子性来提供一些预定义数据的序列化访问。
好。 我理解这个问题。我曾经研究过这个问题。
现在首先需要了解的是两个CPU之间存在的共享内存的工作情况。 因为这些共享内存可以以不同的方式访问,所以你需要弄清楚哪一个最适合你。
大多数情况下,硬件信号将与硬件中断一起提供到共享内存中,以通知从一个处理器到另一个处理器的消息传输。
所以先看看这个。
一个非常好的方法是只是来回发送IP数据包(使用套接字)。 这有一个好处,就是你可以测试片外的东西,就像在PC上运行一个进程的测试版本一样,如果你有网络的话。
如果两个处理器都是由单一操作系统管理的,那么当操作系统负责处理所有事务时,可以使用任何标准的IPC来相互通信。 如果他们在不同的操作系统上运行,那么套接字将是你最好的选择。
编辑
快速单向版本:
在里面:
init() { ready = 0; done = 1; }
作家:
send() { while (!done) sleep(); /* copy data in */ done = 0; ready = 1; }
读者:
poll() { while (1) { if (ready) { recv(); } sleep(); } } recv() { /* copy data out */ ready = 0; done = 1; }
通过共享内存构建一个消息传递系统(通过对两个处理器进行未缓存,或者使用缓存刷新/无效调用,这应该是一致的)。
您的共享内存结构应至少具有以下字段:
Flow可能是这样的:(假设send / recv同步不同步)
poll() { /* you're better off using interrupts instead, if you have them */ while(1) { if (current_owner == me) { if (active) { recv(); } else if (!request[me] && request[other]) { request[other] = 0; current_owner = other; } } sleep(); } } recv() { /* copy data... */ active = 0; /* check if we still want it */ if (!request[me] && request[other]) { request[other] = 0; current_owner = other; } } send() { request[me] = 1; while (current_owner != me || active) { sleep(); } request[me] = 0; /* copy data in... */ /* pass to other side */ active = 1; current_owner = other; }
如何使用共享内存?
我现在没有一个很好的链接,但如果你谷歌的IPC +共享内存我打赌你找到一些很好的信息:)
你确定你需要这样做? 根据我的经验,最好让编译器和操作系统管理你的进程如何使用多个CPU。