小心CPU cache
|
qiezi
2007-08-21
CPU cache是个容易忽略的问题,一般在单CPU机器上几乎可以忽略这个问题,但在多CPU机器上,这很容易造成困扰。
前段时间写了个上传服务器,单CPU机器上测试很正常,在多CPU上发现一个问题,只要并发大于1个,就有一定的几率造成一些数据紊乱。本来是recv再fwrite写到文件,结果可能recv得到的数据校验结果是错的,而fwrite反而是正确的;或者recv是正确的,fwrite写到文件里的内容是错误的,一般错误的内容只有几个字节,百思不得其解。 后来想到CPU cache的影响,在多CPU情况下会非常突出,上面这个现象正常情况无法解释,于是把一些线程类里面的成员变量改到函数堆栈上,主要是一些接收缓冲区、文件缓冲区,问题就解决了。从那以后几乎不敢在线程间共享任何东西,一些lock free的队列也有些不敢用了,出点问题很难测试出来。 如何避免CPU cache的影响?这方面有什么资料吗? |
|
|
bigpanda
2007-08-22
Java 5里面的memory model讲的就是这个。
目前C/C++标准没有提到内存模型,所以编译器可以随便优化。但是在C/C++里面可以直接用内嵌汇编指令,memory barrier,来解决这个问题。 我这点皮毛知识,都是看Java 5 Concurrency学来的。平时工作也不用这些东西,所以也没有实战经验。去网上找找memory model, memory barrier,资料一大把。 这个网页:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html 里面给了个C++的伪码。要解决这个问题还得去看Intel的汇编手册。 另外可以看看能不能用 Intel Thread Building Block 这个库来写多线程程序。 |
|
|
qiezi
2007-08-23
经过讨论和搜索相关资料,线程在CPU间切换时会清掉cache,所以不会造成这个原因,CPU cache只会影响多线程共享。仔细检查代码发现上面这个原因竟然是公司一个老的日志库缓冲区溢出,这个缓冲区和线程里面使用的接收缓冲区是同一个池分配的,结果。。
|
|
|
bigpanda
2007-08-23
哈哈,这个例子再一次告诉我们,千万不要一拍脑子想当然,结论不要下的太快。
|
|
|
qiezi
2007-08-23
是啊,反面教材。。
|
|
|
pi1ot
2007-08-25
这个帖子有意思
|
|
|
dayn9
2007-09-13
刚看但这个帖子我满腹狐疑,从来没有听说过多CPU或多核的出现过缓存一致性问题呀,最多是构架不良为维护缓存一致性,会带来效率下降而已。难道qiezi老大发现了堪比奔腾浮点错误的CPU大bug?
总算真相大白,虚惊一场。 |
|
|
liuqinglqlq
2008-05-27
我汗...刚来就被老大吓一跳啊
|

