1

我在多计算机环境中工作,其中两台计算机将通过 32 位 PCI 总线访问相同的内存。

第一台计算机只会写入 32 位 int。
*int_pointer = number;

第二台计算机将仅从 32 位 int 读取。
number = *int_pointer;

两个操作系统 / CPU 都是 32 位架构。
带有 PCI 的计算机是基于 Intel 的。
PCI卡上的电脑是power PC。

我担心的情况是,如果只读计算机在读取变量的同时更改变量,导致读取计算机的数据无效。
我想知道读取/写入内存中相同位置的原子性是否保留在多台计算机上。

如果是这样,以下是否会阻止竞争条件:

number = *int_pointer;
while(*int_pointer != number) {
    number = *int_pointer;
}

我可以保证每 16 毫秒 * 发生一次写入,而读取将随机发生。

*时间会漂移,因为两台计算机都有不同的计时器。

4

2 回答 2

2

没有足够的信息来明确回答这个问题。

如果任何一个 CPU 决定将内存缓存在*int_pointer,这将始终失败,并且您的额外代码将无法修复任何竞争条件。

假设两个 CPU 都知道内存*int_pointer不可缓存,并且该位置*int_pointer在 4 字节/32 位边界上对齐,并且 PCI 卡上的 CPU 具有 32 位内存接口,并且指针被声明为指向AND两者的指针您的 C 编译器正确实现了 volatile,那么更新很可能是原子的。volatile

如果不满足上述任何条件,结果将是不可预测的,您的“竞争检测”代码可能无法正常工作。

编辑解释为什么volatile需要

这是编译到 MIPS 汇编器的竞争条件代码-O4,没有volatile限定符。(我使用 MIPS 是因为生成的代码比 x86 代码更容易阅读):

int nonvol(int *ip) {
  int number = *ip;
  while (*ip != number) {
    number = *ip;
  }
  return number;
}

反汇编输出:

        00000000 <nonvol>:
   0:   8c820000        lw      v0,0(a0)
   4:   03e00008        jr      ra

编译器已经优化了while循环,因为它知道*ip不能改变。

volatile以下是相同的编译器选项会发生什么:

int vol(volatile int *ip) {
  int number = *ip;
  while (*ip != number) {
    number = *ip;
  }
  return number;
}

反汇编输出:

        00000008 <vol>:
   8:   8c820000        lw      v0,0(a0)
   c:   8c830000        lw      v1,0(a0)
  10:   1443fffd        bne     v0,v1,8 <vol>
  14:   00000000        nop
  18:   03e00008        jr      ra

现在while循环没有被优化掉,因为 usingvolatile已经告诉编译器*ip可以随时更改。

于 2013-05-21T01:31:26.363 回答
0

回答我自己的问题:

没有竞争条件。外部 PCI 设备上的内存控制器将处理所有内存读/写操作。由于所有数据载体的宽度至少为 32 位,因此在这些 32 位中不会出现竞争条件。

由于传输使用 DMA 控制器,因此内存和处理器之间的交互表现良好。

请参阅直接内存访问 -PCI

于 2013-08-29T20:48:30.897 回答