范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

C开发者怒了这个无用的模块设计最终会害死C!

  2018 年年底,C++ 标准委员会历史上规模最大的一次会议在美国 San Diego 召开,讨论了哪些特性要加入到
  C++20
  中。其中,Modules 便是可能进入 C++ 20 的一大重要特性:"一直以来 C++ 一直通过引用头文件方式使用库,而其他90年代以后的语言比如 Java、C#、Go 等语言都是通过 import 包的方式来使用库。现在 C++ 决定改变这种情况了,在 C++20 中将引入 Modules,它和 Java、Go 等语言的包的概念是类似的,直接通过 import 包来使用库,再也看不到头文件了。"
  然而就是这一特性,前段时间在 Twitter 上引发了不小的讨论。再加上诸多其他问题,"
  C++ 20 还未发布就已凉凉
  "的论调也早有苗头。C++ 模块化,究竟是问题多多的无用尝试,还是如期待般能带来其承诺的性能升级呢?
  作者 | vector-of-bool
  译者 | 苏本如
  责编 | 仲培艺
  出品 | CSDN(ID:CSDNNews)
  以下为译文:
  C++ Modules(模块化)被视作 C++ 自诞生以来最大的变化,其设计有几个基本目标:
  1. 自顶向下隔离:模块的"导入程序"不能影响正在导入的模块的内容。导入源中编译器(预处理器)的状态与导入代码的处理无关。
  2. 自下而上隔离:模块的内容不会影响导入代码中预处理器的状态。
  3. 横向隔离:如果两个模块由同一个文件导入,则它们之间不会"串扰"。导入语句的顺序无关紧要。
  4. 物理封装:只有模块显式声明为导出的实体才会对使用者可见。模块中未导出的实体不会影响其他模块中的名称查找(除了 ADL 可能有一些不同之处【依赖实参的名字查找】,但这就说来话长了)。
  5. 模块化接口:强制任何给定模块的公共接口在称为"模块接口单元"(MIU)的单个 TU 中声明。模块接口子集的实现可以在称为"分区"的不同 TU 中定义。
  如果你期望 Modules 可以像 C++ 的许多其它功能一样经久不衰,那么你会注意到上面这个列表中缺少了"编译速度"。然而,这是 C++ Modules 模块最大的承诺之一。模块带来的速度提升可能就是归功于上面的设计。
  下面我列出从 Modules 设计中受益匪浅的 C++ 编译的几个方面,按照从最明显到最不明显的顺序:
  1. 标记化缓存(Tokenization Caching):由于 TU 的隔离,当模块后面导入另一个 TU 时,可以缓存已经标记化的 TU。
  2. 解析树缓存(Parse-tree Caching):和标记化缓存一样。标记化和解析是 C++ 编译中开销最大的操作之一。我自己的测试显示,对于具有大量预处理输出的文件,解析可能会占用高达 30% 的编译时间。
  3. 延迟重编译(Lazy Re-generation):如果 foo 导入了bar,然后我们修改了 bar 的实现,我们可以不需要对 foo 立即重新编译。只有对 bar 接口修改后才需要重新编译 foo。
  4. 模板专门化:这一点比较微妙,可能需要更多的工作来实现,但潜在的加速是巨大的。简而言之,模块接口单元中出现的类或函数模板在经过专门化处理后可以在磁盘上缓存并供后续需要时加载。
  5. 内联函数代码复制缓存:内联函数(包括函数模板和类模板的成员函数)的代码复制结果可以缓存,然后由编译器后端重新加载。
  6. 内联函数省略代码复制:extern template 允许编译器省略对函数和类模板执行代码复制,这对编辑器的代码去重操作非常有益。模块允许编译器隐式执行更多的 extern template-style 优化。
  看上去模块设计相当不错,不是吗?
  但是我们都忽略了一个非常可怕且极为糟糕的缺陷。
  还记得…… Fortran 吗?
  FORTRAN 实现了与 C++ 的设计有点相似的模块系统。几个月前,SG15 工具研究小组在圣地亚哥提交了一篇文章(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1300r0.pdf),据我所知,这篇文章迄今为止没有得到任何相关人士的讨论和评论。
  文章要点摘录如下:
  1. 我们有模块 foo 和 bar,分别由 foo.cpp 和 bar.cpp 定义。
  2. bar.cpp 里有 import foo; 语句。
  3. 在编译 bar.cpp 时,如何确保 import foo 被解析?当前的设计和实现有一个为 foo 定义的所谓"二进制模块接口"(简称BMI)。这个 BMI 是文件系统中描述模块 foo 导出接口的文件。我就叫它 foo.bmi, 文件扩展名在这里无所谓。
  4. foo.bmi 是编译 foo.cpp 的副产品。编译 foo.cpp 时,编译器将生成 foo.o 和 foo.bmi。因此,必须在 bar.cpp 之前编译 foo.cpp!
  趁着警铃还没有拉响,我们来讨论一下我们目前使用头文件的工作方式:
  1. 我们有一个模块 foo,由 foo.cpp 和 foo.hpp 定义; 和另一个模块 bar,由 bar.cpp 和 bar.hpp 定义。
  2. bar.cpp 中有 #include <foo.hpp>。
  3. 在编译 bar.cpp 时,如何确保 #include<foo.hpp> 被解析?这很简单:确保 foo.hpp 存在于 header 搜索路径列表的目录中。我们不需要做任何额外的预处理。
  4. 对模块 foo 和 bar 的编译没有次序要求,可以并行处理。
  并行化可能是提高 build 性能最重要的方面。优化 build 时,你无需再考虑并行化,因为它已经存在了。
  模块改变了这一点。模块的导入导致了一个编译时间的依赖项,这在 #include 语句中并没有体现。(关于模块编译的次序问题,可参考:https://vector-of-bool.github.io/2018/12/20/build-like-ninja-1.html)。
  Rene Rivera 最近在《Are modules fast?》(https://bfgroup.github.io/cpp_tooling_stats/modules/modules_perf_D1441R1.html)一文中探讨了这种设计的后果。
  剧透一下 Rene 文章的结论:答案是否定的,或者更准确一点来讲,这很微妙,但大多数情况下答案仍然是不。这篇文章中使用的当前模块实现是非常原始的,但仍然在了解哪些模块看上去对性能有帮助这方面有一定的参考价值。可以期待,随着硬件并行性的提升,header 的引导模块变得越来越重要,而且与 DAG 深度(即互相导入的模块链的长度)也有关系。随着 DAG 深度的增加,模块会越来越慢,而 header 则保持相当稳定,即使是对于接近 300 的"极端"深度。
  一个徒劳的扫描任务
  假设我有下面的源文件:import greetings;
  import std.iostream;
  int main() {
  std::cout << greeting::english() << "\n";
  }
  这很简单。因为我们导入了一些模块,所以我们需要先编译 greetings 和 std.iostream,然后才能编译这个文件。
  那么,让我们来……
  emmm……
  怎么啦?
  我们只有一个包含两个 import 的源文件,仅此而已,别无他物。我们不知道 greetings 是在哪里定义的,我们需要找到这个包含 module greetings; 语句的文件。
  在银河系另一侧的 talk.cpp 文件看起来很可能是:module;
  #ifdef FROMBULATE
  #include <hello.h>
  #endif
  #ifndef ABSYNTH
  export module something.pie;
  #endif
  import std.string;
  export namespace greeting {
  std::string english();
  }
  它定义了我们想要的 greeting::english 函数。但是我们怎么知道这是正确的文件呢?它并没有 module greetings; 这一行!
  但它某些时候确实是我们要的。当我们使用 -DFROMBULATE 编译时,文件 hello.h 会被粘贴到源文件中。让我们看看 hello.h 里面有什么?#ifdef __SOME_BUILTIN_MACRO__
  # define MODULE_NAME greetings
  #else // Legacy module name
  # define MODULE_NAME salutations
  #endif
  export module MODULE_NAME;
  Oh no!
  好吧好吧……别担心。我们需要做的就是……运行预处理器来检查文件中是否出现 module salutations 或 module greetings。
  这是可以的,但是有 4201 个文件可以定义可以被导入的模块,其中任何一个都可能有 module greetings;。
  另外,我们还不能使用自己的预处理器实现,需要精确地运行编译这段代码的预处理器。看到 __SOME_BUILTIN_MACRO__ 了吗?我们不知道那是什么。如果我们没有正确地对它进行编译,编译就会失败。更糟的是,我们甚至可能会错误地编译此文件。
  那么我们能做什么呢?我们可以在预处理完所有文件后缓存所有模块的名称,对吗?那么,我们在哪里存储这个映射表呢?当我们想用一个不同的编译器编译,生成不同的映射表时会发生什么?如果我们添加需要扫描的新文件怎么办?为了检查任何模块是否添加、删除或重命名了,我们是否需要在每次构建时搜索这些包含了数千个源文件的所有目录?在那些启动进程和/或访问文件需要较大开销的系统上,这些成本也将会叠加上去。
  可能的解决方案
  这两个问题虽然不同,但却是相关的,我(和许多其他人)认为模块设计的一个改变可以解决这两个问题, 那就是模块接口单元的位置必须是确定的。
  有两种备选方案可以实施:
  1. 强制从模块名称派生 MIU 文件名。这模拟了头文件名的设计,它与如何从 #include 指令中找到头文件名直接相关。
  2. 提供一个"manifest"或"mapping"文件,描述基于模块名的 MIU 文件路径。此文件需要用户提供,否则我们将同样遇到上文描述的扫描问题。
  有了确定且易于定义的 MIU lookup(查询),我们就可以进入下一个必要步骤:必须延迟生成模块的 BMI。
  TU 之间的编译顺序将扼杀 module adoption 的进程。即使是相对较浅的 DAG 深度也比与头文件相同的深度慢得多。唯一的答案是 TU 编译必须是可并行的,即使是导入其他 TU 时。
  在这方面,C++ 最好模仿 Python 的导入实现:当遇到新的导入语句时,Python 将首先找到对应于该模块的源文件,然后以确定性的方式查找预编译的版本。如果预编译版本已经存在并且是最新的,就使用它;如果不存在预编译版本,则将编译源文件,并将生成的字节码写入磁盘。然后加载此字节码。如果两个解释器实例同时遇到同一个未编译的源文件,它们将竞争写字节码。不过,竞争并不重要,它们都会得出相同的结论,并将相同的文件写入磁盘。
  为了方便 DAG 中 TU 的并行编译,C++ 模块必须以相同的方式实现。提前编译 BMI 是不可能的。相反,当编译器第一次遇到有关模块的 import 语句时,应该延时生成 BMI。Build 系统根本不应该与 BMI 有关。
  只有当一个 MIU 的位置对于编译器是确定的时候,以上这些才能实现。
  前景渺茫
  前段时间,Twitter 上发生的事让人心烦意乱。Kona 会议前的邮件列表在 1 月 25 日开放了。在发布的许多文章中,有一篇《关注模块的工具能力(Concerns about module toolability)》(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1427r0.pdf),其作者和贡献者名单中很多是来自业界的系统和工具构建工程师。我想呼吁权威人士的关注,但我觉得这份名单中的人才是最有资格提供 module toolability 反馈的人。
  这篇文章的诞生源于许多工具作者和合作者(并不局限于论文中所提及的,包括我自己)的关注,因为大家都深深感到自己长久以来对于模块的关注都被忽视了。
  SG15 之外的人一直热衷于反驳关于 module toolability 问题的讨论,他们声称 SG15 缺乏必要的实现经验,无法对模块这个话题提出有用的建议。
  SG15 只搞过面对面的会议,上次在圣地亚哥的会议也没起到什么作用,因为主席不在,而且大家急急忙忙参会,没时间进行任何有用的讨论。由于在官方的 WG21 会议之外没有安排 SG15 会议,因此其成员很难保证更新并协同工作。此外,SG15 曾多次尝试重提已经被拒绝的问题,被拒绝的原因是因为他们提出的问题被认为"超出了 C++ 语言范围"。
  关于 Kona 会议前邮件列表的推文催生了关于 C++ 模块化的讨论:关于 module toolability,该相信谁?(https://twitter.com/horenmar_ctu/status/1089542882783084549)。
  这场讨论最终以要求 SG15 "他妈的闭嘴"而告终,除非 SG15 能够提供代码示例来证明它们所提到的问题。但是这个示例代码,无法在当前的任何编译器中实现,也不能在任何当前的构建系统中实现。所以即使这些问题确实存在,这个要求也只能得出一个否定的结论,因为这是一个无法凭经验完成的任务。也就是说,要求 SG15 提供代码根本是一个无法永远完成的任务。
  这些问题没有继续讨论下去,也没有被推翻。甚至没有人再提到 《关注模块的工具能力》中列出的问题。我们只是被简单地告知要相信一些大人物比我们更了解 C++ 模块(这里我要再次呼吁权威人士介入)。
  支持目前模块设计的人尚未证明模块能适应大规模生产环境,但是他们却要求 SG15 提供模块不能满足大规模生产的证据。尽管已有的模块部署并没有使用当前的设计,也没有使用真实环境中构建实际系统所需的自动模块扫描。
  如果模块被合并,结果发现它们不能以良好的性能和灵活的方式实现,那么人们就不会使用模块。如果一个 broken module 建议被合并到 C++ 中,后果可能是不可弥补恢复的,C++ 也将永远得不到模块设计承诺带来的好处。
  至于针对当前模块设计的改进方案能成功解决这些问题呢?我不能给出确定的答案,但我和许多人都认为 C++ Modules 有重大问题需要解决。
  然而,从其他人的做法来看,SG15 怎么想似乎并不重要,他们的提议总是被缺乏 C++ 工具经验的人否决, 他们在整个讨论中没有任何发言权,提出的任何问题都被认定为"未经证实"和"超出范围"而不予考虑。
  我不太敢指责这种行为的后果,我也并不热衷"人际冲突"。然而,我更担心 C++ 这个无用的模块设计最终会害死自己。原文:https://vector-of-bool.github.io/2019/01/27/modules-doa.html
  本文为 CSDN 翻译,如需转载,请注明来源出处。作者独立观点,不代表 CSDN 立场。

什么是b2bb2c?哪个平台好?小白问答专栏每天为你解决一个金融理财问题,喜欢欢迎点赞,并转发到朋友圈哦这些高大上的英文简称其实都是电商的商业模式。那他们究竟是啥?又有什么区别呢?在解释他们之前,我们必须了解它的你觉得头条能取代百度吗?至少在目前,今曰头条替代百度的可能性不大。我也是今日头条注册登录的网友。掏心话说,今日头条所具备的功能,感觉和百度尚有一定的距离。百度云集了搜索广告云盘文库解答等等方方面面的诸多功满分100分,你给荣耀V10打多少分?我给95分吧,可以说几乎完美了。拥有麒麟970加上EMUI8。0软硬AI相结合,更好的拍照,更快的快充,AIcamera等等,都让荣耀V10成为人工智能手机领域独一无二的存在。具体华为手机如何删除文件管理里面没用的文件?华为手机受到很多朋友们的喜爱,今天阿饱就给大家带来关于华为清理内存的小技巧!手机使用时间长了,系统的软件不断的在更新,手机用了两三年之后,渐渐的开始变慢了,这时候人们就想要清理清理千元机当中,性价比超高的5G手机是哪款?千元机当中,性价比最高的5G手机是哪款?目前来说,5G手机已经很普及了,一千出头就可以买到许多不错的中端5G手机了,考虑到这位伙伴的需求是千元机,那自然不能整太贵了。目前价格下探到宁波已在开发个人房源自主挂牌功能,预计不久后即可上线!你会撇开中介买卖二手房吗?杭州市住房保障和房产管理局日前在旗下杭州市二手房交易监管服务平台上,上线个人自主挂牌房源功能,引发广泛关注。此举被称作杭州二手房交易去中介化。简单而言,这个功能,可以让二手房房东自苹果手机哪些方面比较好?文小伊评科技作为一个曾经坚定的安卓系统死忠粉,目前我正在使用iPhone12这款手机。在使用苹果手机的过程中,我其实是带着批判性的眼光来看待苹果手机以及IOS系统的,可以理性的不带有没有无灯的耳机?非常适合学生党的入门级蓝牙耳机分享!本文全是干货,是专门写给新手的蓝牙耳机选购攻略,推荐的10款蓝牙耳机也都各有特色,绝对能满足大多数朋友,欢迎mark以便长期浏览。好了,Lets卢克文是中专学历,为什么分析国际大事能力那么厉害?1。中专只是他的第一学历,后期的学习过程你只是不了解而已2。读万卷书,行万里路。读书是很重要,但社会阅历也是自我成长中极为重要的方面3。你所看到的不仅仅是一个人,而是团队的力量,就看到有人说一加8可以闭着眼睛买,有那么好吗?一加的座右铭不将就,一加手机目标用户是追求品质生活的年轻用户,在每个工艺细节都尽量做到最好。一加8可以闭着眼睛买,是有一定道理的。下文具体说一说。一加8的配置屏幕一加8全系采用了A老式80年代电视机什么配件组成?80年代的电视机以黑白电视为主流,一般由电源变压器把市电降到18V左右的交流电,通过整流滤波输出约20V左右的脉动直流电,通过电源电路的调整稳压,分两路输出。一路(即约20V左右)
iPhone12新增全新紫色更新查找功能发布全新配件AirTag2021年4月21日消息2021苹果春季发布会正式举行,带来的第一款产品,竟是iPhone12全新配色紫色,新配色总是让人错不及防。紫色iPhone12第一眼上山去十分有个性,非常电商互联网企业可以没有WMS和TMS,为什么都有OMS,一文章告诉真相电商互联网企业中可以没有WMS,没有TMS,为什么都要有一套OMS呢?一篇文章告诉你真相一什么是OMS,WMS,TMSOMS(ordermanagesystem)接受客户订单信息,爆料汇总苹果今晚春季发布会可能有哪些产品4月20日,距离苹果明天凌晨的发布会还有几个小时。至今我们除了iPadPro之外仍不知道苹果究竟会发布一些什么产品,按照历年来苹果的春季新品发布会,都是针对iPad的升级,以及Ai2030年的中国2030年的中国将会是什么样子。1。中国会超越美国成为世界第一大经济体迈入中等发达国家水平2。中国到那时台湾将成为一个省或一个特区3。路面上的无人驾驶汽车(包括公交车,地铁,的士,五菱神车意味着什么来源经济日报打破特斯拉销冠神话的,不是闪耀在聚光灯下的蔚小理,而是个头不大的五菱宏光MINIEV。中汽协最新数据显示,今年3月份五菱宏光MINIEV销量达到3。98万辆,连续7个月永不妥协的特斯拉接连犯了三个错误,换来价值1500亿的教训无论是企业还是个人,要建立一个良好的口碑都需要漫长的时间和不懈的努力,但是要毁掉这一切就容易得多了,而且可能在一夜之间。昨天的特斯拉,再次验证了这句话,因为上海车展门事件等因素影响歌尔推出新一代扬声器技术方案日前,歌尔推出新一代扬声器技术方案,并带来了微型扬声器SBSTM和大扬声器Cyclone两个品牌的技术升级。针对智能手表等产品的圆形表盘外形设计,以及轻薄化发展趋势,歌尔特别推出全华为实测上道!科技巨头开始跑步造车作者科技日报记者刘艳编辑刘莉4月19日,重回线下的上海车展吸引了爱车人的目光。除传统车企外,众多互联网企业,还有一些听起来与车八竿子打不着的科技企业也挤进了造车的赛道。搭载华为Hi车顶维权让特斯拉再陷风波!车主此前已多次维权,售后经理回复惹人发笑,央媒评论谁给了特斯拉不妥协的底气每经编辑王晓波车顶维权事件再次将特斯拉推上了舆论的风口浪尖。针对这一热点事件及特斯拉公司全球副总裁陶琳回应称没有办法妥协,这是新产品发展必经的一个过程,还强调自己的调研显示,90的你会买吗?华为卖车两驱版售价21。68万中国经济周刊经济网讯4月19日,华为终端官方正式宣布,将正式开启汽车售卖业务,首款车型为赛力斯华为智选SF5。目前,该车已经上线华为消费者官网。自2021年4月21日起,用户即可到数字货币雪崩,华为造车再刮旋风,赚钱效益引发黄金投资机会比特币周末日跌幅超过15,以太坊瑞波币柚子等数字货币跟随全线暴跌。全球爆仓将近45亿美元。究其原因,一市场传闻,美国财政部或将指控多家金融机构使用加密货币进行洗钱。第二土耳其将宣布