本文将描述应用于本地及全局前后发生次序关系的栅栏操作。
早先,我们介绍了称为“栅栏”(fence)的同步原语。栅栏可以利用获得存储器次序、释放存储器次序或这两种次序同时使用。一个具有获得语义的栅栏称为一个获得栅栏;而具有释放语义的栅栏被称为释放栅栏。
一个全局释放栅栏A全局同步于一个全局获得栅栏B,如果存在原子操作X和Y,两个操作都对某个全局原子对象M操作,使得A次序发生在X之前,X修改M,Y次序在B之前,Y读到的是由X所写的值,或是假定X为释放次序,Y读到的是在X释放次序中任一副作用所写的值。如果X为一个释放操作,并且A和B在存储区域上是相包含的,那么X操作会在Y之前。
一个全局释放栅栏操作A全局同步于一个原子操作B,B对一个全局原子对象M执行一次获得操作。如果存在一个原子操作X,使得A次序发生在X之前,X修改M,而B读到的是由X所写的值,或是假定X为一个释放次序,B读到的是由X释放次序中任一副作用所写的值。如果X是一个释放操作,并且A与B在存储区域上是相包含的,那么X操作会在B之前。
一个对全局原子对象M的执行释放操作的原子操作A全局同步于一个全局获得栅栏操作B。如果存在某个对M的原子操作X,使得X次序发生在B之前,并且读到由A所写的值或者由发生在A之前的释放次序中任一副作用所写的值,并且A和B在存储区域上是相包含的。
一个本地释放操作A本地同步于一个本地获得栅栏B,如果存在原子操作X和Y,两个操作都对同一个原子对象M进行操作,使得A次序发生在X之前,X修改M,Y次序发生在B之前,并且Y读到的是由X所写的值,或是假定X操作具有一个释放语义,那么Y读到的值是由释放次序中的任一副作用所写的值。如果X是一个释放操作,并且A和B的存储区域具有相包含性,那么X操作将会在Y之前。
一个本地释放栅栏A本地同步于对一个本地原子对象M执行一次获得操作的原子操作B,如果存在一个原子操作X,使得A次序发生在X之前,X修改M,并且B读到的值为由X所写的值,或者假定X具有释放语义,那么B读到的值由释放次序中的任一副作用所写。如果X是一个释放操作,并且A和B的存储区域是相包含的,那么X次序将在B之前。
对一个本地原子对象M的一个释放操作的一个原子操作A本地同步于一个本地获得栅栏操作B,如果存在某个对M的原子操作X,使得X次序发生在B之前,并且X读到由A所写的值,或者由A之前释放次序中的任一副作用所写的值,并且A和B是相包含的。
设X和Y是两个工作项栅栏,每个同时具有CLK_GLOBAL_MEM_FENCE和CLK_LOCAL_MEM_FENCE标志。如果X要么本地同步于Y,要么全局同步于Y,那么X同时本地同步于并全局同步于Y。