1.1:Interlocked系列函数都提供64位版本,以下文字不将64位版本函数,具体请参考书上
1.2:Interlocked系列函数在x86平台下工作原理是在总线上维持一个硬件信号,这个信号会阻止其他CPU访问同一个内存地址
1.3:调用一个Interlocked系列函数只会暂用50个以下CPU周期,而进行一次用户态内核态模式切换一般在1000个CPU周期以上
确保锁变量和锁所保护的数据在不同的高速缓存行,不然会损伤性能,下面是我的理解:
CONDITION_VARIABLE cv;
InitializeConditionVariable(&cv);
SleepConditionVariableCS(&cv,pCS,INFINITY);
SleepConditionVariableSRW(&cv,pSRW,INFINITY,0或者Share);//0表示独占方式,Share共享方式
WakeConditionVariable(&cv);
WakeAllConditionVariable(&cv);
//CONDITION_VARIABLE不需要Delete,因为操作系统底层不使用它
一个CPU获得锁,从而修改锁所保护的数据,这会引起其他在循环等待此锁变量CPU的高速缓存行失效,因为锁变量和锁保护的数据在一起,这些CPU又会去读取锁变量,一直这样循环
另一个猜测是:如1.4.2所示的循环锁一样,如果g_bUse为true,为其赋值g_bUse=true不会引起其他引用了此变量的高速缓存行失效.
1.4:Interlocked系列函数包括以下几个
1.4.1:InterlockedExchangeAdd(&g_x,-1);InterlockedIncrement(&g_x);InterlockedDecrement(g_x);
1.4.2:InterlockedExchange(&g_bUse,true);使用这个函数创建一个简单的循环锁例子:
while(InterlockedExchange(&g_bUse,true)==true)
Sleep(0);
此函数会设置g_bUse为true,并返回之前的g_bUse值
使用这段代码的线程应该关闭线程动态优先级提升,使所有线程都处在同一优先级水平,否则会影响性能
旋转锁在单CPU环境下意义不大,最好旋转次数经验值为4000次
1.4.3:InterlockCompareExchange(PLONG,LONG,LONG);
这个函数将参数1和参数3比较,如果相同,则将参数2赋值给参数1,所有操作都是原子的
1.5:Interlocked系列函数还定义了一些被称为Interlocked单向链表栈的函数,具体参考书上
2:高速缓存行
2.1:当CPU从内存读取一个字节数据时,并不只是取回一个字节,而是取回一个高速缓存行,取决于CPU,这个高速缓存行大小为32,64,128字节
2.2:当CPU1修改自己高速缓存行的一个字节时,会通知其他CPU,这会使其他CPU高速缓存行作废,CPU1会将自己的高速缓存行写回内存
2.3:GetLogicalProcessorInformation()可以获得CPU高速缓存行大小,但是我搞了半天得不到,好像Windows没实现这个函数,坑爹啊,但x86高速缓存行是32字节,IA64是64字节
2.4:用如下方法控制数据在不同的高速缓存行
#define CACHE_ALIGN 32
struct _declspec(align(CACHE_ALIGN)) stElement
{
int a;
int b;//a,b在一个高速缓存行中
_declspec(align(CACHE_ALIGN))
int c;
int d;//c,d在另一个高速缓存行中
};
2.5:最好的避免高速缓存行引起性能损失的方式是:使用函数参数和局部变量,这些数据存在于线程栈中,不会引起上述问题,还可以使用线程关联性始终只让一个CPU访问一块数据,这也不会引起上述问题
备注:关于高速缓存行我的理解
每个CPU都有一个Cache,每个Cache由多个高速缓存行组成,每个高速缓存行大小应该等于数据总线宽度,可以把在Cache中的高速缓存行看成一个数组,数组的索引是内存地址的