栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 20 内存模型(一)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 20 内存模型(一)

C++ 20 内存模型(一)

多线程的基础是优秀的内存模型

C++20 内存模型:

  • 高复杂性, 难以理解
  • 对多线程有更深入的理解
内存布局 位域

member_name成员名, width bit 宽度

struct bit_field_name
{
    type member_name : width;
};
struct my_struct
{
	char a;
	int b : 5; // 最大存储 2^5 ,只使用低五位节约空间...
	int c : 11,
		: 0,
		d : 8;
	int e;
	double f;
	string g;
};
位域的对齐

不允许跨越 uint 大小的区域

struct my_struct2
{
	char a;
	int c : 30;
	int b : 5;
};

c: 30 bit + 空2 bit + b 5 bit

例子:

#include 
#include 
using namespace std;

struct my_struct
{
	char a;
	int b : 5;
	int c : 11,
		: 0,
		d : 8;
	int e;
	double f;
	string g;
};


int main(int argc, char* argv[])
{
	my_struct s{
		.a = 'a',
		.b = 1,
		.c = 2,
		.d = 3,
		.e = 4,
		.f = 5.0,
		.g = "hello"
	};
	cout << &s << endl;
	cout << "sizeof(my_struct) = " << sizeof(my_struct) << endl;
}

使用内存查看工具查看内存

**这种方式可以解决内存伪共享问题: **

来举一个java多线程的例子

class MyObject
{
private long a;
private long b;
private long c;
}

按照Java规范,MyObject的对象是在堆内存上分配空间存储的,而且a、b、c三个属性在内存空间上是近邻,如下所示。

a(8个字节) b(8个字节) c(8个字节)

我们知道,X86的CPU中Cache Line的长度为64字节,这也就意味着MyObject的3个属性(长度之和为24字节)是完全可能加载在一个Cache Line里的。如此一来,如果我们有两个不同的线程(分别运行在两个CPU上)分别同时独立修改a与b这两个属性,那么这两个CPU上的Cache Line可能出现如下所示的情况,即a与b这两个变量被放入同一个Cache Line里,并且被两个不同的CPU共享。

根据MESI协议的相关知识,我们知道,如果Thread 0要对a变量进行修改,则因为CPU 1上有对应的Cache Line,这会导致CPU 1的Cache Line无效,从而使得Thread 1被迫重新从Memory里获取b的内容(b并没有被其他CPU改变,这样做是因为b与a在一个Cache Line里)。同样,如果Thread 1要对b变量进行修改,则同样导致Thread 0的Cache Line失效,不得不重新从Memory里加载a。如此一来,本来是逻辑上无关的两个线程,完全可以在两个不同的CPU上同时执行,但阴差阳错地共享了同一个Cache Line并相互抢占资源,导致并行成为串行,大大降低了系统的并发性,这就是所谓的Cache伪共享。

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1038865.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号