Windows Via C/C++:用户模式下的线程同步——Cache行
来源:互联网 发布:数据库管理员薪资 编辑:程序博客网 时间:2024/05/16 12:27
为了提升运行在多处理器上的程序的性能,你应该了解CPU Cache的概念。当CPU从内存中读取某个字节时,它会按Cache中数据块大小(也就是Cache行大小)将一整块数据读到CPU的Cache中。比如Cache数据块大小是32,则内存地址按Cache行大小对齐形成0~31、32~63、……、32n~32(n+1)这样的块,当要读取的字节地址为41时,CPU将把包含该地址的整个内存块(32~63)读入Cache中。用公式表示时,假设Cache行大小为C,待读取的变量地址为Addr,则CPU读取内存块的地址是 (Addr/C)*C~(Addr/C+1)*C。将数据读入Cache后,CPU就可以在速度较高的Cache中操作该值,而不用每次都通过数据总线操作内存。
然而,在多处理器环境下,Cache可能会使内存更新出现一些问题,以其中的某一行为例:
- CPU1从内存中读取了一个字节B,导致与其相邻的Cache行大小的字节被读入CPU1的Cache行CL1中
- CPU2从内存中读取同样的字节B,这样与其相邻的Cache行大小的字节又被读入到CPU2的Cache行CL2中
- CPU1更改了B的值,此时CL1中B的值已被改变,但尚未写入到RAM中
- CPU2访问B,问题就出现在这里,CPU2从CL2中读到的B的值和CPU1的CL1中的B值没有同步更新
上面的情形是灾难性的。当然,CPU的设计者们已经从硬件角度解决了这个问题,当某个CPU核心Cache行中的值改变时,其它CPU核心将会得知这一改变并刷新自己的Cache。在上面的第4步中,CPU1会把CL1的内容写入内存,然后CPU2重新从内存中读取数据并写入CL2中。可以看出,Cache在多处理器环境中可能会使系统性能下降。 这一切意味着你应该将代码中的数据按照Cache行大小边界对齐,并把只读(或读操作频繁的)数据和读-写数据分开,把经常同时访问的数据组织在一起。
下面是一个设计比较糟糕的结构:
struct CUSTINFO { DWORD dwCustomerId;// Mostly read-only intnBalanceDue;// Read-write wchar_tszName[100];// Mostly read-only FILETIMEftLastOrderData;// Read-write};
可以调用GetLogicalProcessorInformation函数查询当前系统CPU的Cache行大小,具体用法可查阅MSDN。一旦获得了Cache行大小,就可以使用C/C++编译器的__declspec(align(#))对齐变量了,下面是改进后的CUSTINFO结构:
#define CACHE_ALIGN 64struct __declspec(align(CACHE_ALIGN)) CUSTINFO { DWORD dwCustomerId;// Mostly read-only wchar_t szName[100];// Mostly read-only // Force the following memebers to be in a different cache line _declspec(align(CACHE_ALIGN)) int nBalanceDue;// Read-write FILETIME ftLastOrderData;// Read-write};
关于__declspec(align(#))指令的细节,请参阅http://msdn2.microsoft.com/en-us/library/83ythb65.aspx。
- Windows Via C/C++:用户模式下的线程同步——Cache行
- Windows Via C/C++:用户模式下的线程同步——概述
- Windows Via C/C++:用户模式下的线程同步——临界区 Critical Sections
- Windows Via C/C++:用户模式下的线程同步——Condition Variables 条件变量
- Windows Via C/C++:用户模式下的线程同步——原子操作:Interlocked函数族
- Windows Via C/C++:用户模式下的线程同步——轻量级读写锁(Slim Reader-Writer Locks)
- Windows Via C/C++:用户模式下的线程同步——原子操作:Interlocked函数族
- Windows Via C/C++:内核模式下的用户同步——成功等待的副作用
- Windows Via C/C++:内核模式下的线程同步——WaitForSingleObject/WaitForMultipleObjects函数
- Windows Via C/C++:内核模式下的线程同步——概述
- Windows Via C/C++:内核模式下的线程同步——事件内核对象
- 《Windows via C/C++》学习笔记(四)用户模式的“线程同步”
- Windows Via C/C++ 读书笔记 5 用户模式的线程同步
- Windows线程同步—用户模式下的线程同步
- 《windows via C++》之windows线程同步
- 《windows via C++》之windows线程同步
- 《windows via C++》之windows线程同步
- 《Windows via C/C++》学习笔记 —— “线程同步”之“检测死锁”
- 稀疏矩阵乘法【未写完】
- 对frameset、frame、iframe的js操作
- IE的PNG黑边及字体锯齿
- 加油
- 软件人加油站 -
- Windows Via C/C++:用户模式下的线程同步——Cache行
- 左线性文法标示符识别的c++实现
- 用Win 7,让Ghost安心“退休”(图)
- 非递归遍历二叉树
- 信息检索(IR)
- 中断号与芯片管脚关系
- CSS 笔记(一)
- 可变参数的实现
- 两个数最大公约数