应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

如果Python4。0摆脱了GIL

  作者:orenwang,腾讯IEG应用开发工程师
  导语GIL,即全局解释器锁,是阻碍Python多线程并发计算性能提升的最大原因,也是众多Python开发者的心头之痒,而SamGross大神的新项目nogil却在过去几个月的时间里硬生生地撬开了这把锁。
  Thereshouldbeoneandpreferablyonlyoneobviouswaytodoit。
  ZenofPython
  1992年的一天,Python之父GuidovanRossum为Python引入了一种简单而又优美的机制:让程序运行无需再担心死锁,因为全局只有一把锁;功能实现更加简洁,无需再针对单个对象加锁和解锁,因为全局只有一把锁;甚至大幅提高了计算速度,这来源于程序本身的低Overhead和独特的GarbageCollection机制,因为全局只有一把锁。这把锁就是GIL,即全局解释器锁。
  我们快进到1998年,硬件行业在这一年发生了一个重要的变化:多核处理器被研制出来了。大家很快意识到GIL在单线程领域的强大,却成为了多核计算时代的绊脚石。因此在1999年Python1。4版本期间出现了一个叫freethreading的包,大刀阔斧地移除了GIL,然而单线程计算速度却慢了4到7倍。
  而我所知道的最近一次移除GIL的尝试是2016年LarryHastings大神提出的Gilectomy项目,其移除了GIL之后单线程计算仅慢了30,然而该项目的主要问题在于核越多,计算越慢(7核下慢19倍)。
  由此可见,Guido爸爸写的这段代码,尽管每天被全球开发者吐槽,但真搞起来,想比人家做得更好并不容易。GIL的问题
  举一个简单的例子:给你一张纸,上面有100个格子,让你从数字1写到100,一个格子一个数字,你觉得需要多久?我闲来试了一下,花了我82秒(好像真的很闲)。那好,现在假设你们有五个人,每个人只要写其中20个数字即可,你觉得需要多久?简单地看,82秒除以5,五个人大约16秒即可完成。但如果你们五个人只有一支笔呢?算上你们互相传递笔的时间,恐怕82秒也不够了。
  纸上画数字的例子(动画内可以想象成100个人100支笔同时写字)
  上面的例子里,这支笔,在Python的世界里就是GIL:无论你们有多少人,只能有一个人拿着笔,其他人只能等着这个人把笔放下,才能开始写字;无论你的Python程序起了多少个线程,真正吃CPU干活的只有一个线程。之所以这里强调了一下吃CPU,是因为GIL的设计仅对CPUbound的程序有限制,而在处理IObound计算时,是不需要GIL这支笔的,大家可以同时干IO的活。
  这时很多人会好奇,为什么不直接使用multiprocessing库进行多进程计算呢?当然可以,但是multiprcessing的实现实际上是fork了个新的进程,性能牺牲了不说,死锁的问题也将会暴露出来,更不用说如CUDA等很多第三方库是不支持fork的。
  再说一点,实际上,大部分人吐槽GIL的点,并非是Python程序本身并发效率的问题,而是大多数对于计算速度有要求的库都是Python调用CC,而GIL限制了你在调用CC时也只能真正同时运行一个线程。也难怪Sam大神想要移除掉GIL,他作为PyTorch的核心作者,自称因性能问题曾大面积地把Python代码完全重写成了CC,也因此很多人说PyTorch跟Python关系已经不大了。相比之下,Swift团队曾写过一篇WhySwiftforTensorflow点出了相比Python的GIL性能瓶颈,Swift在训练AI的性能方面具备优势;而Python的第一竞品Julia开发者和爱好者们更是揪着GIL这一点屡屡不放手,怂恿大家转向使用Julia做数据科学工作。
  综上,现今GIL怕是过大于功了。一些不那么基础的基础知识
  接下来,本文会讲解一些技术细节,虽然尽可能写得通俗易懂(从而不暴露自己其实也不懂),但如果不够熟悉Python的话可能还是会觉得有些不知所云。。。CPython
  简单来讲,CPython就是我们用的Python。只是为了更容易地与Python这门语言进行区分,我们一般把运行Python解释器的这个引擎叫做CPython(我一开始就把CPython跟Cython项目搞混了,但其实Cython和我们本文说的就不是一回事了,它只是个把Python变成C的工具)。那除了用C写的CPython,其实还有用Java和C分别写的Jython和IronPython。值得注意的是,后两者并没有GIL,因此GIL并不是Python这个语言的特性问题,而是CPython实现中包含的,因此下文与GIL相关的都会用CPython这个名字进行阐述。ReferenceCounting
  当你有了变量的时候,CPython就已经开始计数(counting)了,而当这个变量出现在任一列表(list)或者字典(dict)或者函数(function)内的时候,计数都会增加。当使用变量的函数执行完毕,或这个变量被pop出了某一个列表的时候,CPython就会把这个变量的计数对应减少。而当某个变量计数为零的时候,这个变量所在的内存就可以被释放掉了,可以看CPython源码这里(https:github。compythoncpythonblobmainIncludeobject。hL520)就是这么写的。
  具体计数方式也可见下面的代码例子,我个人觉得看代码更容易理解:
  而这个ReferenceCounting有意思的地方就在于:程序释放变量对应的内存空间无需等待GC工作时再进行操作了!因为只要计数为零,就满足了条件。那为什么CPython还是需要GC呢?我这里一下子也没想通,查阅了一下资料发现原因其实很简单,因为如果有几个变量没其他地方用到了,但是它们互相之间是有reference的,那这个时候仅靠ReferenceCounting去释放内存自然就会发生内存泄漏。Atomicity
  继续用上面纸上写数字的例子,当你在写数字17时,你要先写个1,再写个7吧。可能在你写7之前,会有人把你的笔抢走,这个OK。但你起码不能在写1写到一半的时候,允许别人打断你。换句话说,你要有一个最原子的行为,这个行为无法进一步再拆分,你就Atomic了。
  这个概念,有一些数据库知识基础的话,应该不需要解释,跟大部分数据库所保证的Atomic是不同场景下的同一个意思。ConcurrentCollectionProtections
  列表(list)或者字典(dict)这类对象,我们都可以称之为Collection,这些对象往往在类似Python这种语言内都有各自独特的内存结构,有的结构倾向于计算速度,而有的结果是出于内存占用考虑进行了优化。但无论哪种结构,在出现并发的的情况下,这些Collection都存在线程安全问题,因此处理时底层往往有一定的并发锁逻辑进行保护,这个相信不难理解。改写历史的nogil项目的技术细节
  Sam大神的新项目nogil之所以获得了如此大的关注度,也首次引起CPython核心团队好评的原因不仅是它成功移除掉了GIL(而非类似perinterpreterGIL那种半移不移的设计),同时也克服了绝大多数前人未能解决的问题,而且最终性能分数惊人。通读了Sam的原paper后,我又翻阅了几篇大神们对该工作的讨论和文章,感觉这个项目成功的核心倒不是设计上有多么巧妙(当然人家非常非常非常巧妙),难得的是nogil把Python目前版本里几个浪费掉的地方拎出来逐一进行了深度优化,只不过深到已经把Python的内存分配器PyMalloc都直接换掉了。正像LarryHastings所说,难的不是移除掉GIL,难的是移除掉了GIL还能保证以前的东西就像没移除掉一样好用。。。那Sam是怎么做到呢?这里讨论下我觉得比较有意思的几点:BiasedReferenceCounting
  这其实是2018年ACM上的一篇论文BiasedReferenceCounting提出的一种全新ReferenceCounting理论:并发多个线程同时进行ReferenceCounting操作时,我们往往需要把每一次操作Atomic化,这样才能保证各个线程之间得到的count值保持一致;但我们忽略了一个因素,如果一个对象经常会被某一个线程操作,而被其他线程操作的频次很少,那我们是不是可以给这一个类似owner的线程一些特殊的优化,即便让其他的线程慢一点也影响不大?
  而事实上,绝大多数对象都是面临这样一种情况。所以,这里我们就Biased了,让owner线程的ReferenceCounting操作速度达到极致,而不用保证Atomic,只需要让其他所有的线程Atomic即可(好吧,这里我也不是很懂,为什么NonAtomic就一定比Atomic要快,但我知道为了做到Atomic显然要做某些牺牲,等有时间我再具体看看为啥,然后补充到这里)。这一点非常关键,是整个nogil项目对性能贡献最大的一点,我画了个动画帮助理解:
  Immortalization
  上面的BiasedReferenceCounting好用的前提是大多数变量只有一个线程会经常使用,但对于那些0、1、True、False、None之类的变量呢?这些变量可是几乎每一个线程都要频繁使用的。为了提高这类变量的操作速度,Sam很巧妙地把这些变量Immortalize(永久化)了,使得这类变量的引用不再需要做计数!我看到了这里,就有种强烈的md我怎么没想到的感觉。
  不过实现Immortalization也不是没有牺牲的:计数值的LSB(最低有效位,LeastSignificantBit)不能再用了,因为LSB被用来代表这个变量是不是可以永久化掉了。这里会结合下面的DeferredReferenceCounting再多讨论一些。DeferredReferenceCounting
  继续揪着ReferenceCounting不放:那些既不能被永久化掉的同时又需要频繁使用的对象怎么办(怎么有点谐音梗。。。)?这个第二低有效位也被拿来征用了,被用来表示某个对象是否需要Defer它的引用计数。这个Defer的意思我个人感觉有一点误导,因为它其实并非延后,根本就是不再计数了,把所有释放相关的工作都交给GC(GarbageCollector)了,毕竟很多引用的toplevelfunctions或者modules本来就是只能被GC给释放掉。
  这里的具体实现我也不是很懂,但知道大概是因为局部变量一般是在内存的Stack上,DeferredReferenceCounting是完全不用管Stack上的计数变化,但如果一个对象的引用是被放在Heap上的,这个时候计数其实是照常的,只不过不会因为Heap上的计数为0而直接释放掉它,毕竟这个时候有可能有Stack内存还在引用它。
  Immortalization和DeferredReferenceCounting加起来一下就用掉了两个最低位,也就是说以后每次调用PyINCREF和PyDECREF,ReferenceCount每次变化就是4了,感觉怪怪的。不过按Sam的原话,这里其实变化是1还是4并不重要,毕竟我们大部分情况下只关心这个计数是不是零就够了。这么说,也确实有些道理。Mimalloc
  Python的内存分配器PyMalloc被换成mimalloc了。看mimalloc文档看到第二段就感觉好厉害:
  mimallocisadropinreplacementformallocandcanbeusedinotherprogramswithoutcodechanges
  这哪里是换掉PyMalloc,这原来是可以直接换掉malloc了
  具体实现细节我就没有看了,因为我知道我肯定看不懂。但是这里使用它的原因就很明显了:因为PyMalloc有GIL的保护,所以不需要也做不到threadsafe,而mimalloc可以让Python做到threadsafe同时性能大幅提升。CollectionReadonlyAccess
  写到这里,终于写到了码农们熟悉的list和dict对象了。
  当我们引用或一个list或dict对象,发生的过程大致可以简单地分成三个步骤:加载这个对象的地址修改对象的ReferenceCount返回这个对象的地址
  这一切在GIL的保护下没什么问题。然鹅现在我们没有GIL了,这里会出现一个问题:当有一个线程执行写操作时,在步骤2把这个对象释放掉了(ReferenceCount减少到0),而这个时候又有一个线程已经完成了步骤1,开始直接步骤2时,就崩溃了,因为这个对象已经被释放掉了。
  Sam的设计是,既然我们没有GIL这把全局锁了,我们就要给单个对象加局部锁,不过我们只对写操作加锁。具体实现简单来说就是增加了ReferenceCounting版本控制和更多的检查判断并重试机制,比如在执行上述的步骤2时首先检查对象是否ReferenceCount已经为0了,如果是的话,从步骤1开始重试(重试之后我理解就可以读到一个新的地址或是可以识别出是空地址从而保证安全性)。
  目前对于list和dict的重新设计,主要是对单线程处理速度进行了优化,对于多线程处理只能保证安全而速度上有一定程度的牺牲。也许以后会出现一些特殊的collection类型,以应对那种多线程频繁调用的情况。Python4。0是否真的会移除GIL?
  我个人感觉,出现一个没有GIL版本的Python4。0的可能性是比较大的,毕竟CPython核心团队其实已经在着手将Sam大神的nogil项目合入Python3。11了,而且该项目的性能分数已经达到甚至部分超过了Guido爸爸之前对于拿掉GIL的基本条件,这一次没有借口可以拒绝了。当然Python3。11多半不会是一个无GIL版本,nogil项目无论多强大它也还只是个实验项目,其仍存在诸多大小问题,以及很多仍待讨论的架构决策,都不是一个小版本就能够解决掉的。
  至于Python4。0,它自己本身就是个未知数。核心团队自己已经重申了多次他们想尽量延后Python4。0的时间,因为Python2。0到3。0大家已经很伤了,这么快又搞一波怕大家心里承受不了Guido爸爸很久就曾发推解释过一次:
  这里我想吐槽一下,从Python3。5开始,每个版本就已经很伤了好么还不如赶紧上nogil也算是个痛并快乐着。
  无论结果如何,我作为一个被Python领进门的、被Python各种骚操作种草的、到现在不管后端服务还是客户端脚本还是各种AI小研究都首选Python的忠实粉丝,衷心祝愿Python未来。。。越来越妖!

元宇宙记鹿一张图看懂8家元宇宙巨头一张图看懂8家元宇宙巨头一、Roblox:当今最接近元宇宙的平台二、Unity:交换标准类三、Fastly:算力基础四、Autodesk:交换标准……苏宁易购被破产了?7月5日,市场上有传闻称,有供应商向法院申请苏宁易购(ST易购,002024。SZ)破产清算。中城院要案中心表示,7月4日,在中城院要案中心的帮助下,有两名供应商寄出材料……李盈莹是如何崛起的?东京周期00后主力球员,郎平唯一关门弟子中国女排已经成功拿到了一张世界女排联赛总决赛的门票,8胜4负的成绩对于一支刚刚经历了低谷、换帅,并重新组建的队伍来说,已经算是非常出色的成绩了。在12场比赛中,作为中国女排最强……膝盖酸疼发冷如何是好?一张临床方送给你大家好,我是赵医生,今天给大家讲一个最近遇到的一个膝盖冷痛的患者。膝盖冷痛可以说在骨科病症中非常常见,同时也是上了岁数的患者经常会遇到的一类问题,那这位患者是什么情况呢?……顺滑好用的iPad书写工具,随时拿起就能用,南卡Pencil在日常工作学习中,平板无疑是非常实用的工具,搭配电容触控笔使用,更是可以大幅提升效率,不过对于使用iPad的朋友来说,官方的ApplePencil虽然性能出色,但是价格对于学生……首轮28顺位的普尔季后赛场均28。7分,同期选秀前三顺位现状场均28。7分3篮板4。7助攻1抢断,投篮命中率66。7,命中率59。1,真实命中率83。9联盟第四,比赛贡献值19,位列联盟第8,这是季后赛三场比赛过后,勇士球员普尔交出的场……吃好了今天,吃丢了明天一篇福寿螺的事件,勾起了强烈的反思头条是个非常好的平台,可以了解更多的事情,今天看到的《福寿螺事件》还看到一个《老年人看男科》的文章,让我思绪万千,决定写下这篇文章。……辟谣!关于维生素AD的谣言三连你信了几个仅供医学专业人士阅读参考你信了几个?随着儿童保健工作的深入开展,如今家长可以轻松获得关于婴幼儿维生素AD补充的专家共识、循证文献和科普好文,做到科学育儿。但是……23岁塔图姆,儿子已年满4岁!技术流的他也有望实现父子同台?NBA成立这么久还没有球星能实现父子同台,最有希望父子同台的球星可能是詹姆斯和他的儿子布朗尼。但是詹姆斯已经37岁,我们无法保证未来几个赛季詹姆斯的健康以及状态。布朗尼虽然是老……没钱你就别生二胎我是一个二胎妈妈,我的孩子们在一天天的长大,而我在焦虑中渡过每一天。儿女双全的快乐很快被育儿的琐事以及教育问题所淹没,我的二胎初心是让大宝多个伴,可我现在无比后悔把二胎生下来,……凌晨1点,皇马做出明智决定!姆巴佩很意外,球迷盛赞豪门气质关于姆巴佩这个夏天会去到哪里,其实已经非常明确了,只会是前往皇马或者留在大巴黎。本来前往皇马是一个非常大概率的事情了,但是随着这几天大量球队想要强留下来他的言论,也是让事情变得……为何马云能见多国领导人,而马化腾刘强东却不行?差距在哪?随着香港疫情形势日益严峻,更多企业向香港伸出援手。就在18日,阿里巴巴通过旗下阿里巴巴公益基金会,向香港首期捐赠1000万元港币,支持医护人员的抗疫工作,定向医护人员急需防护物……
穿出职场女王范,做职场魅力女王在职场生涯中,身为美女的你面对每天都要穿的职业都已经麻木了,因为怕职业装遮挡你的美,其实不然,职业装也一样可以彰显你的女性魅力,就比如这身深条纹职业套装就很不错。大方利落的剪裁……足坛传出噩耗,22岁的美国女足队长不幸在宿舍身亡,球迷质疑死我们都知道,中国女足也就是国足女队,在苏州已经隔离完了。接下来,她们就要回到俱乐部去接受接下来的锦标赛和锦标赛的挑战。这对于她们来说,压力是非常大的!因为她们在大年初六打败了韩……同事,其实是个NPC形形色色繁星点点NPC,是英文nonplayercharacter的缩写,往往是游戏中一种角色类型。这类非玩家角色,指的是电子游戏中不受真人玩家操纵的游戏角色,这一概念最……生病的时候不能吃发物,发物到底是什么?一次性给你说明白很多人身体不舒服去看医生开中药,医生都会给你说,发物不要吃,但是发物到底是什么,很多人不清楚,今天我来给大家说一说。那么发物到底是什么呢?中医医生把一切容易动风生痰,发毒……飞腾F2000银河麒麟常用测试工具操作指引适用范围适用于国产化飞腾F2000平台银河麒麟Linux系统常用测试工作操作指引。测试工具目录目录Stream。。3X11perf5iozo……36岁杨幂挺会打扮,礼裙只穿一半时髦有魅力,身材好真占便宜在出席一些重要活动时,我们通常需要在服装搭配上更加精心一些,毕竟,想要展现出女性最美的状态,除了妆容之外,穿搭就是最简单直接的方式了。而说到具体怎么穿,可以多去借鉴女明星们的造……4年前,一夜爆火的发际线男孩小吴,如今怎样了?今朝,人人爱美、追美、成美。看脸的时代,人们愈发注重形象。人靠衣装,马靠鞍,实为真理。有人不惜重金出国整容,对昂贵护肤品绝不错过,还唱响口号今年的衣服配不上明年的我……人到中年,患上脂肪肝,应该吃什么,不能吃什么,医生给你建议脂肪肝吃什么1。芹菜大豆汤100克新鲜芹菜,洗净切块,20克大豆(先用水泡充气),在锅中加入适量水,将大豆和芹菜一起煮,吃豆子,吃蔬菜,喝汤,一天一次,连续三个月,……夺冠热门太阳队解析太阳队三大内线:艾顿,23岁,身高211cm,体重113kg。基大腿,34岁,身高213cm,体重122。5kg。比永勃,29岁,身高203cm,体重116k……FromSoftware公司情况曝光员工在职时间平均高达7年熟悉魂系列游戏的玩家一定对宫崎英高所在的FromSoftware不陌生,而最近该开发商上线的新员工招聘网站透露了公司目前的基本情况,也让我们了解到好的游戏开发商是拥有非常强大的……最佳睡眠时间公布,不是8小时,自查一下,看看你达标了吗?我们每天都要睡觉,而且在平时我们一直强调每天要有充足的睡眠,大多数专家都要求我们每天睡8个小时左右,如果按照7点起床的话,那么11点之前就要上床睡觉,这样才算是生活比较规律的。……混合式主动降噪加迷你充电盒,泥炭SOUNPEATSAir3P随着TWS蓝牙耳机的功能越发成熟,现在选购TWS蓝牙耳机降噪已经成为了必要功能,因为TWS蓝牙耳机少了降噪,就像开放式听歌一样,外界噪音总在作怪,而最近我则是入手了一款主打混合……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网