由一道淘宝面试题到False sharing问题
今天在看淘宝之前的一道面试题目,内容是
在高性能服务器的代码中经常会看到类似这样的代码:
typedef union
{
erts_smp_rwmtx_t rwmtx;
byte cache_line_align_[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_smp_rwmtx_t))];
}erts_meta_main_tab_lock_t;
erts_meta_main_tab_lock_t main_tab_lock[16];
请问其中用来填充的cache_line_align的作用是?
之前有学习到c语言中宏align是内存补齐的作用,那这个不就是cache line补齐?但是啥是cache line??为啥有这么一步?
1.首先,什么是cache line?
CPU处理指令时,由于“Locality of Reference”原因,需要决定哪些数据需要加载到CPU的缓存中,以及如何预加载。因为不同的处理器有不同的规范,导致这部分工作具有不确定性。在加载的过程中,涉及到一个非常关键的术语:cache line。
cache line是能被cache处理的内存chunks,chunk的大小即为cache line size,典型的大小为32,64及128 bytes. cache能处理的内存大小除以cache line size即为cache line。
了解了cache line,然后再熟悉一下cpu上cache的一些策略
2.cpu上cache的策略
cache entry (cache条目)
包含如下部分
1) cache line : 从主存一次copy的数据大小)
2) tag : 标记cache line对应的主存的地址
3) falg : 标记当前cache line是否invalid, 如果是数据cache, 还有是否dirty
cpu访问主存的规律
1) cpu从来都不直接访问主存, 都是通过cache间接访问主存
2) 每次需要访问主存时, 遍历一遍全部cache line, 查找主存的地址是否在某个cache line中.
3) 如果cache中没有找到, 则分配一个新的cache entry, 把主存的内存copy到cache line中, 再从cache line中读取.
cache中包含的cache entry条目有限, 所以, 必须有合适的cache淘汰策略
一般使用的是LRU策略.
将一些主存区域标记为non-cacheble, 可以提高cache命中率, 降低没用的cache
回写策略
cache中的数据更新后,需要回写到主存, 回写的时机有多种
1) 每次更新都回写. write-through cache
2) 更新后不回写,标记为dirty, 仅当cache entry被evict时才回写
3) 更新后, 把cache entry送如回写队列, 待队列收集到多个entry时批量回写.
cache一致性问题
有两种情况可能导致cache中的数据过期
1) DMA, 有其他设备直接更新主存的数据
2) SMP, 同一个cache line存在多个CPU各自的cache中. 其中一个CPU对其进行了更新.
3.为啥需要cache line 补齐呢?
让我们先看一个例子,
举例:
// 如下代码在SMP环境下存在cache频繁刷新问题
double sum=0.0, sum_local[NUM_THREADS];
#pragma omp parallel num_threads(NUM_THREADS)
{
int me = omp_get_thread_num();
sum_local[me] = 0.0; #pragma omp for
for (i = 0; i < N; i++)
sum_local[me] += x[i] * y[i]; #pragma omp atomic
sum += sum_local[me];
}
在做多线程程序的时候,为了避免使用锁,我们通常会采用这样的数据结构:根据线程的数目,安排一个数组, 每个线程一个项,互相不冲突. 从逻辑上看这样的设计无懈可击,但是实践的过程我们会发现这样并没有提高速度. 问题在于cpu的cache line. 我们在读主存的时候,数据同时被读到L1,L2中去,而且在L1中是以cache line(通常64)字节为单位的. 每个Core都有自己的L1,L2,所以每个线程在读取自己的项的时候, 也把别人的项读进去, 所以在更新的时候,为了保持数据的一致性, core之间cache要进行同步, 这个会导致严重的性能问题. 这就是所谓的False sharing问题, 有兴趣的同学可以wiki下.

解决方法很简单:
把每个项凑齐cache line的长度,实现隔离.
|
1
2
3
4
5
6
7
8
|
typedef union {
erts_smp_rwmtx_t rwmtx;
byte cache_line_align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(
sizeof(erts_smp_rwmtx_t))];
} erts_meta_main_tab_lock_t;
或者
_declspec (align(64)) int thread1_global_variable;
__declspec (align(64)) int thread2_global_variable;
|
这就是为什么在高性能服务器中到处看到cache_line_align, 号称是避免cache的trash.
类似valgrind和intel vtune的工具可以做这个层次的性能微调.
http://rdc.taobao.com/blog/cs/?p=523)
http://software.intel.com/en-us/articles/avoiding-and-identifying-false-sharing-among-threads/
由一道淘宝面试题到False sharing问题的更多相关文章
- Expression构建DataTable to Entity 映射委托 sqlserver 数据库里面金额类型为什么不建议用float,实例告诉你为什么不能。 sql server 多行数据合并成一列 C# 字符串大写转小写,小写转大写,数字保留,其他除外 从0开始用U盘制作启动盘装Windows10系统(联想R720笔记本)并永久激活方法 纯CSS打造淘宝导航菜单栏 C# Winform
Expression构建DataTable to Entity 映射委托 1 namespace Echofool.Utility.Common { 2 using System; 3 using ...
- (转)从P1到P7——我在淘宝这7年
(一) 2011-12-08 [原文链接] 今天有同事恭喜我,我才知道自己在淘宝已经七周年了.很多人第一句话就是七年痒不痒,老实说,也曾经痒过,但往往都是一痒而过,又投入到水深火热的工作中去.回家之后 ...
- 从P1到P7——我在淘宝这7年(转)
作者: 赵超 发布时间: 2012-02-25 14:47 阅读: 114607 次 推荐: 153 [收藏] (一) 2011-12-08 [原文链接] 今天有同事恭喜我,我才知道自己在淘 ...
- 从P1到P7——我在淘宝这7年 - 子柳撰写
http://kb.cnblogs.com/page/132752/来自博客园的整理版本,作者是子柳,博客地址:http://blog.sina.com.cn/calvinzhaoc (一) 2011 ...
- 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能
前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...
- python推荐淘宝物美价廉商品
完成的目标: 输入搜索的商品 以及 淘宝的已评价数目.店铺的商品描述(包括如实描述.服务态度.快递的5.0打分): 按要求,晒选出要求数量的结果,并按"物美价廉算法"排序后输出 思 ...
- ip地址库 新浪,淘宝
原文连接地址:http://www.9958.pw/post/city_ip function getAddressFromIp($ip){ $urlTaobao = 'http://ip.taoba ...
- 仿淘宝分页按钮效果简单美观易使用的JS分页控件
分页按钮思想: 1.少于9页,全部显示 2.大于9页,1.2页显示,中间页码当前页为中心,前后各留两个页码 附件中有完整例子的压缩包下载.已更新到最新版本 先看效果图: 01输入框焦点效果 ...
- php单点登录之模拟淘宝天猫同步登录
说到单点登录大家都很了解,一个站点登录其他域会自动登录. 单点登录SSO(Single Sign On)的方法有很多,比如:p3p.共享session.共享cookice.第三方OAuth认证. 这里 ...
随机推荐
- Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)
QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...
- Android dialog 问题
1.dialog.dismiss和dialog.cancel的区别 Cancel the dialog. This is essentially the same as calling dismiss ...
- 基于visual Studio2013解决算法导论之006最大堆排序
题目 最大堆排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #i ...
- swift 自定义TabBarItem
1.效果图 2.NewsViewController.swift // // NewsViewController.swift // NavigationDemo // // Created ...
- mp3播放器
1.视图 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...
- ios9 之后 配置百度地图出现的错误
链接地址:http://blog.csdn.net/u011303663/article/details/48596315 错误 ld: '/Users/xxx/Documents/xxx/Baidu ...
- java class生成jar包(转)
进入dos操作符窗口cd进入要打成jar包的class文件所有文件夹目录jar cvf [生成jar的名称.jar] [列出class文件] //若有多个,以空隔隔开 如:一.操作零散的单个或几个cl ...
- 双绞线的制作,T568A线序,T568B线序
双绞线的制作 1.1 实验目的 双绞线是组建局域网时常常使用的通信传输介质,通过本实验,让学生学会制作双绞线. 1.2 实验任务 (1)了解双绞线的特性及屏蔽与非屏蔽双绞线的区别. (2)了解EIA/ ...
- 【FAQ】SpingMVC实现集合參数(Could not instantiate bean class [java.util.List])
需求,要求批量新增或者改动一个List,在Spring MVC中是不支持以下代码的写法 @RequestMapping(value = "/update", method = Re ...
- CSS未知div高度垂直居中代码_层和布局特效
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...