False share的影响或者解决

转载 2011年01月19日 10:25:00

什么是False share:

False sharing is a well-known performance issue on SMP systems, where each processor has a local cache. It occurs when threads on different processors modify variables that reside on the same cache line, as illustrated in Figure 1. This circumstance is called "false sharing" because each thread is not actually sharing access to the same variable. Access to the same variable, or true sharing, would require programmatic synchronization constructs to ensure ordered data access.

 

怎样寻找False share:

  • objects nearby in the same array, as in Example 1 above;
  • fields nearby in the same object, as in Example 4 of [3] where the head and tail pointers into the message queue had to be kept apart;
  • objects allocated close together in time (C++, Java) or by the same thread (C#, Java), as in Example 4 of [3] where the underlying list nodes had to be kept apart to eliminate contention when threads used adjacent or head/tail nodes;
  • static or global objects that the linker decided to lay out close together in memory;
  • objects that become close in memory dynamically, as when during compacting garbage collection two objects can become adjacent in memory because intervening objects became garbage and were collected; or
  • objects that for some other reason accidentally end up close together in memory.

怎样解决:

First, we can reduce the number of writes to the cache line. For example, writer threads can write intermediate results to a scratch variable most of the time, then update the variable in the popular cache line only occasionally as needed.

 

 

Second, we can separate the variables so that they aren't on the same cache line. Typically the easiest way to do this is to ensure an object has a cache line to itself that it doesn't share with any other data. To achieve that, you need to do two things:

 

  • Ensure that no other object can precede your data in the same cache line by aligning it o begin at the start of the cache line or adding sufficient padding bytes before the object.
  • Ensure that no other object can follow your data in the same cache line by adding sufficient padding bytes after the object to fill up the line.

可以将用户的自定义类型T做一个包装,然后复用

c++的例子:

// C++ (using C++0x alignment syntax)

template<typename T>

struct cache_line_storage {

   [[ align(CACHE_LINE_SIZE) ]] T data;

char pad[ CACHE_LINE_SIZE > sizeof(T)

? CACHE_LINE_SIZE - sizeof(T)

: 1 ];

};



c#的例子:

// C#: Note works for value types only

//

[StructLayout(LayoutKind.Explicit, Size=2*CACHE_LINE_SIZE)]

public struct CacheLineStorage<T>

where T : struct

{

[FieldOffset(CACHE_LINE_SIZE)] public T data;

}



c#和java引用类型会更复杂一点:

For Java and .NET full-fledged objects (reference types), the solution

is basically the same as for .NET value types, but more intrusive: You

need to add the before-and-after padding internally inside the object

itself because there is no portable way to add external padding directly

adjacent to an object.



引用资料:

http://www.drdobbs.com/high-performance-computing/217500206;jsessionid=GE4YIOKZDGNOLQE1GHPCKH4ATMY32JVN?pgno=4

http://www.drdobbs.com/223100705;jsessionid=GE4YIOKZDGNOLQE1GHPCKH4ATMY32JVN?queryText=false+share



备注:

高速缓存行

CPU 的高速缓存一般分为一级缓存和二级缓存。CPU在运行时首先从一级缓存读取数据,如果读取失败则会从二级缓存读取数据,如果仍然失败则再从内存中存读取数 据。而CPU从一级缓存或二级缓存或主内存中最终读取到数据所耗费的时钟周期差距是非常之大的。因此高速缓存的容量和速度直接影响到CPU的工作性能。 一级缓存都内置在CPU内部并与CPU同速运行,可以有效的提高CPU的运行效率。一级缓存越大,CPU的运行效率往往越高。

一级缓存又分为数据缓存和指令缓存,他们都由高速缓存行组成,对于X86架构的CPU来说,高速缓存行一般是32个字节,早期的CPU大约只有512行高速缓存行,也就是说约16k的一级缓存。而现在的CPU一般都是32K以上的一级缓存。

当CPU需要读取一个变量时,该变量所在的以32字节分组的内存数据将被一同读入高速缓存行,所以,对于性能要求严格的程序来说,充分利用高速缓存行的优势非常重要。而高速缓存行的这一特性针对现在流行的双核及多核CPU来说,却又必须小心对待。

但总体来说,对于普通应用,程序设计人员根本无需考虑高速缓存行的问题,但对于像视频监控这样的特殊应用,尤其是要想充分发挥双核CPU的性能优势,就必须认真对待这些问题。既要避免多线程同步的性能瓶颈又要充分发挥多核多线程的优势。









伪共享(false share)简介

现代计算机都带有很多缓存用于解决CPU极快的计算速度和主存duxie
  • WinWill2012
  • WinWill2012
  • 2014年10月17日 20:49
  • 1060

多线程false sharing带来的影响和一些优化.

最近在线项目中测试一个无锁队列的性能的时候发现,在一个线程push另一个线程pop整型数据的时候,吞吐量竟然和std::queue+spinlock类似甚至更差,这样完全体现不出lockfree的优势...
  • zxjcarrot
  • zxjcarrot
  • 2015年09月09日 22:08
  • 447

return false影响事件冒泡

在编写zepto, jquery的事件时,回调函数体中不要使用 return false , 这将阻止事件冒泡,会导致其他的函数捕捉不到事件。 比如前一阵,某位同事无意中修改了一个tap事...
  • sinat_17775997
  • sinat_17775997
  • 2017年03月19日 22:08
  • 344

关于ajax为什么要return true/false

一  举例 function addZone(){    $.dialog({        lock: true,        title: '添加',        width: '650p...
  • yangliu4683
  • yangliu4683
  • 2017年11月02日 14:05
  • 96

Tomcat 安装后问题处理

安装完tomcat6后,启动tomcat /usr/share/tomcat6/bin# ./startup.sh 后,报如下错误: Using CLASSPATH:       /usr/sha...
  • fengguowuhen7871
  • fengguowuhen7871
  • 2013年04月25日 13:49
  • 1885

ios::sync_with_stdio(false);(读入优化)

在竞赛中,遇到大数据时,往往读文件成了程序运行速度的瓶颈,需要更快的读取方式。相信几乎所有的C++学习者都在cin机器缓慢的速度上栽过跟头,于是从此以后发誓不用cin读数据。还有人说Pascal的re...
  • liangzhaoyang1
  • liangzhaoyang1
  • 2016年06月23日 10:56
  • 542

WPF X:Shared概述

一、含义 X:Shared用于指定请求资源时创建实例的两种方式。 X:Shared = “true”(默认):表示所有请求都是共享同一个实例。一般不显示指定。 X:Shared = ...
  • tudou880306
  • tudou880306
  • 2017年05月25日 16:39
  • 177

thrift使用

一、thrift介绍 1.Thrift概述    Thrift是一个跨语言的服务部署框架,最初由Facebook开发用做系统内部多种语言之间的RPC通信,07年四月开放源码,08年5月进入apache...
  • u012875880
  • u012875880
  • 2014年03月11日 16:23
  • 1709

ExpandableListView常见问题

pressureListView.setGroupIndicator(null);  设置去掉默认的右侧的箭头 pressureListView.setOnGroupClickListener...
  • tianhongfan10106
  • tianhongfan10106
  • 2017年03月26日 13:48
  • 198

share pool使用率过高分析原因

数据库升级至10.2.0.5后发现share pool使用率99%,剩余几十M,目前share pool已经7.5G了,所以决定查找一下为什么share pool占用率那么高。 这条sql可以查询s...
  • hxf0759
  • hxf0759
  • 2012年05月16日 11:25
  • 4111
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:False share的影响或者解决
举报原因:
原因补充:

(最多只允许输入30个字)