2013-12-16 46 views
3

如果我有一个整数x,下列哪些语句在iPhone上的ARM架构上是原子的?哪些整数操作在ios/arm平台上是原子的?

int x; 
int y; 
x = 92; // . . . . . . A 
x++;  // . . . . . . B 
y = ++x; // . . . . . . C 
printf("x = %d\n", x); // D 

我知道,在i386平台上,语句A,B和D是原子的,而C不是。我很确定C在iOS中不是原子的。我怀疑基本的加载和存储操作(D和A)在iOS中也是原子的,但我不确定。有谁知道更多?

它是如何与16位和8位值?或者iPhone 5S上的64位值和iPhone 5及更低版本上的64位值?

(如果答案是,因为我怀疑...有任何平台,基本负载和存储操作不是原子?)

+0

我不太确定B是在i386原子:)你试图做什么?你可以使用操作系统同步原语吗?例如OSAtomic ...函数系列https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW14 – yurish

+0

他们不是原子的,他们创造了一个完整的记忆障碍。但是否则他们是,我想。例如如果x是23,一个线程通过调用x ++来更改它,而另一个线程同时访问x,那么其他线程在加载x时将得到23或24,但不是-817376或21. – Michael

+0

我可能是错的,但认为原子性是语言的东西而不是平台。当你说上述操作是原子的时候,你依赖于编译器的实现细节。 – yurish

回答

2

你不给就xy声明足够的上下文。如果函数中有本地人,那么他们将被分配到寄存器,而其他线程不能触摸它们。所以我认为你的意思是他们是全球性的(或者至少是静态的)。

ARM是一个加载存储体系结构。它没有内存内存说明。所以真的只有线A/D是原子。你无条件写下价值。它不是与另一个线程相关的。如果一个线程写入92,而另一个线程写入29,那么将无法知道没有某种类型的互斥锁写入的内容。

Early ARM cpus have swp;但大多数iOS产品将使用ldrexstrex。您必须使用这些说明进行任何种类的原子更新。

ARM可以一次写入8/16/32/64位,并且大多数系统设计将具有同步的高速缓存,以便另一个CPU可以看到一个CPU的写入。环形缓冲区结构可以与生产者/消费者一起使用,其中只有一个CPU写入环形头,另一个CPU写入环形尾部;也就是说,这将是一个原子结构,您可以在没有swpldrexstrex的情况下使用。

如果你手动分配一个64位的值,你可能会搞砸了。你将不得不努力做到这一点。例如,如果在64位值的高/低32位之间发生页面错误。显然,取决于CPU类型,未对齐的值也可能有问题。如果你正常的声明,它们应该被编译器很好的对齐。这也可以通过未对齐的 32位和16位值来实现。 iOS可能会使这些访问看起来原子为用户空间。一般来说,如果你依赖原子行为,你不应该做任何奇怪的强制转换,并正常地声明变量。

编辑:

(如果答案是,因为我怀疑...有任何平台,基本负载和存储操作不是原子?)

是的,有许多平台的大值加载/存储不是原子的;特别是对于所有数据类型。实际上,大多数CPU至少有8位(尽管有4位CPU),所以加载和存储通常是原子的。对于较小的CPU,较大值的加载/存储可能需要几个周期。在这些情况下,编译器将花费多个周期来更新值。这是sig_atomic_t背后的想法;它是一个可以自动更新的可变大小。 sig_atomic_t应在所有Posix systems上可用,但在普通C99中没有一般保证。 C11添加了_Atomic类型限定符。

+0

谢谢!是的,我的意思是全局或静态变量。 “物品A/D是原子”是什么意思? A/D代表什么?我的理解是否正确:如果x是92,一个线程将其更改为29,那么另一个线程将会看到92或29,但不是完全不相关的值?知道缓存有多大可能会变得很有趣?一切事情总是在几毫秒内或几秒钟内同步,或者偶尔会同步甚至更长时间? – Michael

+0

是的。那是对的。也许值'0xffee0000UL'和'0xddccUL'会更好。没有办法看到'0xffeeddccUL'或只是'0x0UL'或其他组合。 'str'和'ldr'是一个单独的指令,不中断运行。在多CP​​U设计中,高速缓存/内存被保留并广播,因此不同的CPU看不到不同的值。 * A/D *是您的物品/行* A *和* D *。 –