17

我使用 C# 已经有一段时间了,最​​近开始致力于为我的一个副项目添加并行性。因此,根据微软的说法,对整数甚至浮点数的读写都是原子的

我确信这些原子性要求在 x86 架构上运行得很好。但是,在诸如 ARM(可能不支持硬件浮点)之类的架构上,这些保证似乎很难。

仅由于“int”始终为 32 位这一事实,问题才变得更加重要。有许多嵌入式设备不能原子地执行 32 位写入。

这似乎是 C# 中的一个基本错误。保证这些数据类型的原子性不能移植。

这些原子性保证如何在没有 FPU 或 32 位写入的架构上实现?

4

5 回答 5

12

通过运行时检查来保证原子性并不难。当然,如果您的平台支持原子读取和写入,您的性能可能不会那么高,但这是一个平台权衡。

底线:C#(核心语言,不包括一些特定于平台的 API)与 Java 一样可移植。

于 2010-09-29T19:17:00.197 回答
8

未来发生在昨天,C#实际上是移植到大量嵌入式内核上。.NET Micro Framework 是典型的部署方案。我看到列为本机目标的型号是 AT91、BF537、CortexM3、LPC22XX、LPC24XX、MC9328、PXA271 和 SH2。

我不知道他们的核心指令集的确切实现细节,但我相当确定这些都是 32 位核心,其中一些是 ARM 核心。为它们编写线程代码需要最低限度的保证,正确对齐单词的原子更新就是其中之一。鉴于支持的列表和对齐字的 4 字节原子更新在 32 位硬件中实现是微不足道的,我相信它们实际上都支持它。

于 2010-09-29T19:25:33.607 回答
7

关于“可移植性”有两个问题:

  1. 是否可以为各种平台生成语言的实际实现
  2. 是否期望用一种语言编写的程序无需修改即可在各种平台上正确运行

一种语言的保证越强,将其移植到各种平台就越困难(某些保证可能使在某些平台上实现该语言成为不可能或不切实际),但用该语言编写的程序更有可能在存在支持的任何平台上无需修改即可工作。

例如,许多网络代码依赖于这样一个事实:(在大多数平台上)无符号字符是 8 位,而 32 位整数由四个无符号字符按升序或降序表示。我使用了一个 char 为 16 位、sizeof(int)==1 和 sizeof(long)==2 的平台。编译器作者可以让编译器简单地使用每个地址的低 8 位,或者可以添加很多额外的代码,以便编写一个 'char' 指针会将地址右移一位(保存 lsb),读取地址,根据保存的地址 lsb 更新高或低半部分,并将其写回。这些方法中的任何一种都允许网络代码在不修改的情况下运行,但会极大地阻碍编译器用于其他目的。

CLR 中的一些保证意味着在原子操作大小小于 32 位的任何平台上实现它是不切实际的。所以呢?如果一个微控制器需要超过几十 KB 的代码空间和 RAM,那么 8 位和 32 位之间的成本差异非常小。由于没有人会在具有 32K 代码空间和 4K RAM 的部件上运行 CLR 的任何变体,谁在乎这样的芯片是否能够满足其保证。

顺便说一句,我确实认为在 C 规范中定义不同级别的功能会很有用;例如,许多处理器确实有 8 位字符,可以使用联合将其组装成更长的单词,并且有很多实用代码可以利用这一点。为使用这些东西的编译器定义标准会很好。我还希望在系统的低端看到更多标准,为 8 位处理器提供一些语言增强功能。例如,为可以采用运行时计算的 16 位整数、8 位变量或具有常量的内联扩展版本的函数定义重载会很有用。对于经常使用的功能,它们之间的效率可能会有很大差异。

于 2010-09-29T22:48:30.200 回答
6

这就是 CLI 的用途。如果不符合要求,我怀疑他们是否会证明实施。所以基本上,C# 可以移植到任何拥有 C# 的平台。

于 2010-09-29T19:16:19.000 回答
3

为了可移植性而过度弱化保证违背了可移植性的目的。保证越强,便携性就越有价值。目标是在可能的目标平台可以有效支持的内容与对开发最有用的保证之间找到适当的平衡。

于 2010-09-29T21:05:33.807 回答