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

并行下的效率与安全

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

并行下的效率与安全

程序并行下的效率与安全是通过锁(互斥量、自旋锁)和lock-free(原子操作)方式来实现的,由于mutex修试下的临界区是串行的,首先记录下lock-free下的安全问题。

一、基础知识

1、cache line

叫做缓存行,是指cpu从内存中读取数据时总要把目标数据周围的一部分数据都读进来(局部一致性),这样一次读取的一组数据就是cache line,是缓存交换中的最小单位,不同机器存在差别。
cache line被读取进来后会拷贝到内核私有的L1/L2 cache下,当原子变量被修改后,会通知cpu的其他核心来同步变量所在的cache line(cpu一致性同步)。这就存在false sharing现象:当某个变量被多个核心共享时,一个核心对其进行修改就会导致其所在的cache line失效,需要重新从内存读取, cache line中的其他变量也要等待缓存同步而变慢,严重影响整体性能。因此并发编程中为避免这种情况:

  • 频繁被修改的变量要放到单独的cache line中,按cache line对齐。读远大于写的共享变量放到其他cache line里。
  • 对于计数器,被多个线程频繁修改,如果只是用作日志打印之类完全可以用thread local类型,日志打印时再合并变量值,性能能可能有几十倍的差距。

当然cache line同步是当共享变量能被其他核心可见的情况下,比如说全局的原子变量或者volatile修饰的变量。

2、内存序模型 Memoty Fence

原子操作只保证了对变量的访问控制,但是仍存在两种因素导致多线程代码运行结果不符合预期:

-为了提高运行效率,在每个机器周期内运行更多的指令,编译器和CPU会对指令进行重排。原则是单线程下互不依赖的指令进行重排,重拍后单线程下运行没有问题,多线程下就变的不确定了。

//Thread-1									//Thread-2
p.init();	//A							   if (a) 		//C
a = true;	//B							       p.run();	//D

由于单个线程下p和a是不依赖的,所以Thread-1/Thread-2重排后完全可能变成B->C->D->A,这样p就会在为初始化情况下执行,不符合预期。

  • 即使没有重排,p和a的值会在Thread-1执行后独立的同步到Thread-2所在核心的cache,Thread-2仍有可能在看到a==true时看到的是为初始化的p的值。

对解决指令重排,c++提供了6中内存序模型,常用的是Release/Acquire组合,write-release和read-acquire配对使用。详见下面例子。

memory order作用
memory_order_relaxed没有fencing作用, 原子操作默认使用。
memory_order_consume后面依赖此原子变量的访存指令勿重排至此条指令之前
memory_order_acquire后面访存指令勿重排至此条指令之前
memory_order_release前面访存指令勿重排至此条指令之后。当此条指令的结果对其他线程可见后,之前的所有指令都可见
memory_order_acq_relacquire + release语意
memory_order_seq_cstacq_rel语意外加所有使用seq_cst的指令有严格地全序关系

上面的例子更正为:

//Thread-1													
p.init();	//A							
a.store(true, std::memory_order_release);	//B	
			
//Thread-2
if (a.load(std::memory_order_acquire)) 		//C
	p.run();	//D

B指令的write-release保证了A->B,C指令的read-acquire保证了C->D,然后配对使用这一组会先执行write再执行read,就保证了A->B->C->D的执行顺序。

对于cache line的同步问题(可见性),memory fence只能保证可见性指令的顺序性,不能保证指令的可见性,详见:https://github.com/apache/incubator-brpc/blob/master/docs/cn/atomic_instructions.md#memory-fence

参考:
【1】https://github.com/apache/incubator-brpc/blob/master/docs/cn/atomic_instructions.md#memory-fence
【2】https://aaron-ai.com/docs/memory_reordering_simple_analysis/
【3】https://www.boost.org/doc/libs/1_56_0/doc/html/atomic/usage_examples.html
【4】https://www.codedump.info/post/20191214-cxx11-memory-model-2/

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

版权所有 (c)2021-2022 MSHXW.COM

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