2311d9月会议
DLF2023年9月月度会议摘要
Robert
Robert,在DConf上做了一些初步的JSON5工作.他还更新了Bugzilla到GitHub的迁移脚本.他使用了"隐藏"API,现在脚本要快得多.
除此外,他在DScanner上做了一些小事,并等待JanJurzitza(Webfreak)合并它们.他指出,沃尔特曾要求他写一篇演讲,他准备写DScanner相关的博客文章.
亚当
无法访问的代码
亚当首先提出了"无法访问语句"的警告.他说这真很烦人,应该消除它.误报破坏了它提供的价值,且它并不能减少错误.有一个PR可版本化它.
蒂蒙赞成摆脱它,因为他觉得它最烦人.
Steve同意该功能几乎没用.
默认,Dub警告为错误.他说,宁愿看到编译器删除无法访问的代码,也不愿忍受发出警告.
马丁说,同意.对那些想要它的人来说,该功能应该包含在可配置的linter中.它帮助了他几次,但它在很多场合都阻碍了他.
Walter问,在模板扩展中,禁止警告行不行?亚当说可以,但举了个二分法示例,此时,
在assert(0)中,现在它不再编译.
Walter同意这很烦人,亚当说,要看看性价比.
即使收益不为零,成本也是巨大的.
沃尔特同意了,并说如果移除它并放在到检查器(linter)中,问题不大.
丹尼斯,指出,编辑器最好可利用这些信息.如,code-d按灰色显示未使用的参数,因此尽管未用,也不会造成干扰.
他建议禁止dmd中的签入,但保留它的代码,以便DMD库的客户可用它.沃尔特说这很好.
更新:Adam此后修改了他的PR,以便禁止检查但未删除,且已合并PR.
DLF角色
接着,亚当问谁负责标准库,并说曾经是安德烈.我回答说是atila.
Dennis已在YouTube频道上开始了贡献者教程系列,并计划继续下去.
史蒂夫
Steve报告说,他一直试让他的移植Raylib中使用ImportC.他发现ImportC已走了很长一段路.除了一些链接器错误,已到了几乎可工作的地步.
他一直在与Martin合作解决这些问题,并想在下个LDC版本中修复它们.在下个版本的LDC中,他可能会有一个内部启用了ImportC部件的Raylib移植.
他觉得这很令人兴奋.如果ImportC可达到可从C导入要求内容的地步,则会避免创建移植和绑定的许多麻烦.
接着,他说他开始了他的下一个D编程课.但在窗口上,还需要更多改进,以启动和运行一切.
Timon
Timon说,在DConf上,他本来打算修复一些bug,但他尝试了其他事情:他在foreach循环中,解包元组.
然后,他做了个演示.然后他展示了他发现的一个问题.有时候,Phobos元组的实现方式,对结构实例,会导致多次后复制和析构器调用.
解包元组时,情况更糟.最好,可用移动替换所有这些调用.这有点烦人,这是语言的局限性.
Walter感谢他在元组上的工作.
Dennis说,移动语义和复制构造器难以理解.很难理解DIP.阿蒂拉说,这被搁置了,要完成它,现在肯定有不应有的副本.
我建议把Walter的"复制,移动和转发DIP视为一个稳定功能,而不是增强功能.必须把它弄进去.阿蒂拉同意了,因为不应有副本.
虽然,声称有移动,但有时它们不管用.
蒂蒙同意了,并提出,目前没有除运行时系统外,合法方法来释放不变值.
蒂蒙重复了"是没有合法方式".如果函数只是释放不变值,因为它返回void,编译器可省略它.
因为它是纯(pure)的.需要说明要消耗每个值.默认,与析构器一起使用,但应该可有函数说,“我现在正在使用该值”,然后在调用函数后它就消失了.
有core.lifetime.move,但它并没有考虑移除它.它只是默认初化它,然后你再次得到该纯析构器调用.
Martin说Timon的演示很酷,并怀疑他的生命期问题来自胶水层,如果可能,它会直接在最终的局部变量中放置调用函数的结果.
因为一些如结构的构造器等特例,它需要在胶水层中处理.这太丑陋了.如果保持现在接口,则需要在每个胶水层中重新实现元组支持,而不仅是dmd,以使事情正常工作.
Martin继续说:正如Timon所提到的,运行时存在语言限制.基本构建块就在那里,但Timon的析构器示例就是限制之一.
因此Martin一直要求把移动和转发搞成内置,而不是当前库方法.如果内置它们,也可摆脱一些模板膨胀.
当然,也不想要那些额外的后复制和析构器调用,但如果负载非常大,即使是移动的析构成本也可能非常高.如,4kb移动不是免费的.
最好,直接部署.但是很可能要更改AST才行.
Timon感谢Martin的见解.然后,Martin详细介绍了它是如何入侵到语言中,及移动和原位放置的现在的工作原理.
他还说,在DRuntime中发现了多个实现,并试简化一切以使用core.lifetime.move,但最好,move和emplace应该是内置的,而不是库方法.
沃尔特说,很久以前,他就写了转发和移动的DIP,他需要重新熟悉它.他指出,在实现@live中,他对移动语义很感兴趣,因此把移动语义构建到语言中的提议,都可能会对@live产生更好的影响.
所有权/借用系统基于移动而不是复制.不久前,他把DIP交给了Max(当时决定Walter和atila不应再评判他们自己的DIP,事后看来这是一个错误),但它从未完成.
沃尔特说,目前有很多优先事项.阿蒂拉一直在推动他改变shared的语义,他已同意了.
这也阻碍了很多人.然后是ImportC问题(耗时工作).所以他同意应该暂时把移动放一放.
马蒂亚斯
Mathias提出了-preview=in.在过去一次会议上,Mathias同意改变dmd的行为,使其总是按引用(ref)传递(Walter认为有时按值传递,有时按ref传递是不一致).
他报告说,与DConf的Ahrefs讨论后.他们对D的C++整合非常感兴趣.遇见了个问题,因为有些想要按引用传递的类,但是当有接受类为参数的函数时,会按指针管理它.
他们已讨论了按引用传递它的方法.Mathias想要实现概念验证,且已与Walter讨论了.
马丁
马丁说,他一直在为LDC的D2.105而努力.目前,它进展得相当顺利.最新编译器版本,终于可针对Symmetry代码基测试.
已修复一些2.103和2.104回归.为此感谢拉兹万.一切正常.他想可针对2.106.0版本尽早测试Symmetry的代码基.
最后,他告诉Steven,在LDC1.35版本,部分修复他报告的ImportC问题.
Dennis
是测试问题.
拉兹万
模板问题
Razvan从Martin提到已修复回归开始.它们是由Walter的PR引起的,目的是在推导环境时,阻止编译器发出实例化运行时勾挂模板的降级.
他说,一般,找到新的数组式时,你会立即降级它到newarray模板中,然后实例化模板,并分析它,并在某个字段中存储它.
但是,如果该环境是CTFE,则一般,不需要这样.你总要解释该式.但有时,即使在CTFE环境中,仍需要降级.
因此,如果不降级,这时你最终会遇见实例化错误.
他说,这里的方法是总是实例化模板,并按降级保存,但这样,就不必总是为它发出代码.该方法也有问题.前端现在是,在推导环境中,有实例化模板时,它会按不需要生成代码,来标记模板实例.
但是,如果实例实例化其他模板,则不再按推导模板标记这些模板.如果未生成根模板,却生成了子实例,这也会导致问题.
如,他引用了其中一个回归:给定一个实例化map的__ctfe块,按别名参数把λ传递给它,则因为它是在CTFE环境中,就不会把代码降级到勾挂上.
但随后,把λ传递给映射实例化的其他模板,则在这些环境中分析它时,会导致ICE.
需要查看根实例化是什么,并传播不需要codegen它触发的子实例.
马丁说,拉兹万所描述的,一般都应有效.但这很复杂.然后,他详细介绍了推导实例触发的模板实例化.
当前实现有一些问题,也有一些解决方法,但回归与此无关.他说,有时候,依靠新的模板降级来自行生成错误,以抓一些错误情况,对这些失败很不错.
在CTFE中,只需检查是否有问题,会短路它,又因为要假设它总是有效的,会跳过降级.这不会切掉它.这是主要问题.实例化降级模板可能失败时,需要删除这些检查.
这就是已修复问题,现在运行良好.
马丁说,也许最好,在前端去掉降级.Walter建议,也许应该按旧方式在胶水代码中降级.Razvan说,因为现在运行时使用模板,这样做就是放弃了现在这些问题.
还出现了不经常遇见的其他模板问题,但现在在运行时使用了模板,它们更加明显.
他说,另一个问题是属性.这些降级是从各种属性环境中完成的.目前,在实例化模板,如果有循环依赖关系,则推导不管用.
编译器只是假设它们是@system的,不纯的,非@nogc的,等等.这里,不是前端模板降级问题,而是有些需要修复的模板发射或实例化错误.
马丁同意了.
关于属性推导,Timon说,也许这是计算最大而不是最小不动点问题.编译器应总是推导属性,但目前,它不是尽量推导它们.
这不对.但是,如果不自省,要做好就有点麻烦了.
Martin说,过去,Symmetry的代码基就曾受到停止推导属性的打击.编译器有时会跳过它.比如,当在特定实例中,需要它的成员函数之一,且还没有语义分析聚集时.
完全跳过了推导.这很麻烦.
Razvan说,不应codegen的实例,而codegen时,他正在研究该问题.他想找出问题所在.
DMD库中的AST节点
自DConf以来,Razvan一直在考虑DMD库如何提供任意覆盖各种AST类型.
他给了该AST实现使用的表达式类层次的示例:
module expression;
import std.stdio;
class Expression {}
class BinExp : Expression
{void fun(){writeln("expression.fun");BinExp p = new BinExp();Expression e = new Expression();}
}
class BinAssignExp : BinExp
{}
class AddAssignExp : BinAssignExp
{override void fun(){writeln("AddAssignExp");}
}
class MulAssignExp : BinAssignExp
{}
然后在ast_family.d中,默认ASTCodegen如下:
struct ASTCodegen
{public import expression;
}
要创建自定义AST并覆盖如BinExp等的默认,需要执行如下操作:
struct MyAST
{import expression;import std.stdio;alias Expression = expression.Expression;class MyBinExp : expression.BinExp{override void fun(){writeln("MyBinExp.fun");}}alias BinExp = MyBinExp;alias BinAssignExp = ??
}
问题是,为了使用你的自定义实现,必须声明从BinExp继承的所有AST节点.这不可行.
不仅要可指定要覆盖指定节点,还要指定其他节点要用它.
首先,考虑了模板化AST节点,并从模板化版本继承,但要大量修改编译器.然后想出了使用mixin的方法.只需插件(mixin)入期望AST节点的代码即可.
使用该方法,AST节点现在是mixin模板:
module expression_mixins;
import std.stdio;
mixin template Epression_code()
{class Expression {}
}
mixin template BinExp_code()
{class BinExp : Expression{void fun(){writeln("expression.fun");BinExp p = new BinExp();Expression e = new Expression();}}
}
mixin template BinAssignExp_code()
{class BinAssignExp : BinExp{}
}
mixin template AddAssignExp_code()
{class AddAssignExp : BinAssignExp{override void fun(){writeln("AddAssignExp");}}
}//插件.
mixin template MulAssignExp_code()
{class MulAssignExp : BinAssignExp{}
}
然后表达式模块变为:
module expression;
import expression_mixins;
import std.stdio;
mixin Expression_code();
mixin BinExp_code();
mixin BinAssignExp_code();
mixin AddAssignExp_code();
mixin MulAssignExp_code();
//插件.
在ast_family中,ASTCodegen不变,但现在,可如下自定义AST:
struct MyAst
{import expression_mixins;import std.stdio;mixin Expression_code();mixin BinExp_code() t;class MyBinExp : t.BinExp{override void fun(){writeln("MyBinExp.fun");}}alias BinExp = MyBinExp;mixin BinAssignExp_code();mixin AddAssignExp_code();mixin MulAssignExp_code();
}
可在前端库中,自动生成样板.重点是,现在可无需重新声明所有内容,在层次中,用自定义实现替换任意默认节点.
此例中,从BinExp继承的所有内容,现在都从MyBinExp中继承.这管用.这是可行的.
基本上是个可插件的AST,相关丑陋是值得的.
阿蒂拉说他喜欢它.
Razvan指出,问题是语义例程访问器将不再起作用.但很酷的是,也可把它们放在mixin中.用自定义语法树节点,你继承的,并覆盖期望访问节点,混合这些,得到了期望的所有功能.
Timon说,dmd在试构建自己时会有问题.
如"未定义的标识串",一般前向引用错误或ICE等.
Razvan说,他遇见了未定义标识问题,但可在问题点插入别名来解决.这些都是需要修复的编译器错误.
Timon同意了.
Dennis指出,bootstrap编译器不会修复程序.Martin说你要提高bootstrap编译器版本.然后他说,如果,只有单个AST,它就可正常工作.
但是,需要多个AST的工具都需要完全不同的类层次.即使只对小小的BinExp感兴趣,也可能影响其中的几十个类,但不会影响整个数百个类.
你想在AST之间共享一个被覆盖的类.
拉兹万说,这是可以做到的.在AST族,外部声明该类,然后在族内使用别名.
Steve说,问题是,在编译器中查看实现时,你查看BinExpression,并看到AddAssignExpression继承自它,它有可能从与上面完全不同的东西继承.
很难跟踪这一点.特别是如果有个替代的AST,如,对DMD库.跟踪事物去向及继承方式会令人困惑.
Razvan说,如果你正在研究编译器,不应有混淆.在mixin中看到的是实现.不会再有覆盖.对编译器库的用户来说,有点令人困惑,但你仍必须选择要覆盖的AST节点.
他预计接口将比所有这些样板,所有多个插件文件要简单得多.还可以是自动化的.然后,只需要指定要覆盖的类即可.是的,有点令人困惑,但DMD现在的组织方式,他不知道你如何保留代码的当前状态,并继续前进.
Mathias认为目前,这似乎是唯一方法.
沃尔特说还有另一个方法.与其在AST节点之外,不如在节点里面,放置mixin.让AST节点插件至用户定义的模板中.这样,不用折腾,就可添加功能.
拉兹万说他也考虑过,但仍需要定义所有定义.沃尔特说,在主编译器中,只需留空.Razvan同意,但编译器库用户仍必须定义所有AST节点,然后手动插件感兴趣节点.
对史蒂夫评论,这将更丑陋.因为现在,查看表达式实现,第一反应是它很丑陋.但它封装得非常好.你有整个类,只需插件进你的AST族.
他说,这很有效.好处是可逐步实现它.可逐步取每个AST节点,并把它放入mixin中,然后插入进AST代码中,并查看它是否有效.
如果因为编译器错误而遇见问题,则很容易跟踪它.是的,这需要大量更改编译器,但现在,如果不修改所有AST节点,就不可能覆盖它们.
沃尔特说,他不明白为什么把插件放在类里而不是放在类外,就不会完成,只是减小侵入性.atila说你必须定义所有子类.
仍需要手写它们.沃尔特不认为这是真的.Razvan说,你定义你的AST时,仍要写Expression类,然后插件内容.
沃尔特说,你重定义了所有插件内容.史蒂夫说,你可把所有混进去的传递给类.然后用它来插件代码.
Walter说,在你拥有的每个语义节点中,你列举继承等等,然后插件到特征模板中.编译器的函数模板与用户库的函数模板不同.
然后,如果想修改一个AST节点,只需修改该AST节点的mixin.这就是你所要做的.
Razvan问,想添加另一个字段或函数时,会怎样.按参数传递它们?atila说不行,因为必须为此传递与API中的AST节点一样多的mixin,或只传递一个,然后就会插件到每个AST节点中.
沃尔特提出了另一个方法.已从AST中删除了语义阶段,现在它们是单独完成的.可更进一步,删除更多覆盖函数等等.
让AST树像ASTBase中的树,即它只是层次.然后用户可修改它.这只是个想法.只需删除相关编译器的所有AST内容,这样它就更像是个用户无需修改即可使用的空的AST.
拉兹万说,四年前就有该方法,但当时,才开始重构.Razvan认为这是正交的,因为除非还与mixin方法结合使用,否则仍无法向AST添加新字段.
Walter同意它不会添加新字段.阿蒂拉问是否需要.难道不是你在写自己的访问者吗?为什么需要在那里修改AST.
Razvan:因为目前语义阶段在使用AST.解析器需要特定AST结构.因此,如果想添加一些字段来存储一些信息以在语义分析时使用,则…
Timon说,每个类都有插件功能是有效的,因为,你可根据该类型来静如(static if),查看你在哪个节点上,可把你的代码准确注入到正确节点中.
Dennis说,他还不确定DMD库的哪个应用真正需要覆盖类.除了静态增强类,每个AST节点都有个标识,或只是额外的库空针,如何?则无需繁重模板和插件机制,库可动态转换和读取该字段.
Razvan引用了未用导入工具中的一例.在那里,当编译器解析名字时,在符号类的域中,有个搜索方法.
只要覆盖该方法,再存储一些信息等.
在此,谈话转向了dmd中虚/终函数的使用,为了dmd库,要如何更改,及更改API对用户代码破坏的可能性.
Razvan指出,LF最终可能会由Weka使用的个人项目,希望可修改AST节点.现在,因为未提供适当接口,他必须跳过很多障碍.
Razvan表示,他愿意为此努力,并向dmd提交一些PR,看看是否可行,或是否只是遇见了障碍.他问沃尔特是否赞成探索它,或认为它太丑了.
阿蒂拉重复了一遍,他喜欢它.Walter问其他编译器是如何做到的.这触发了一些关于clang和Java编译器的讨论.
Martin表示,现在不太担心会破坏编译器的API.现在只是用它作dmd库的完整起点.因此,不必担心API的巨大变化.
一旦有了依赖它的稳定工具,那不行了.LLVM有重大API更改.甚至会有三个不同弃用步骤的版本.
D现在不存在.
Walter担心这是对编译器内部的痛苦更改,且不确定这是否值得.编译器中有很多AST节点,现在要全部覆盖它们.
Razvan说,对他来说,与模板化解析器或移出语义阶段时一样.Walter说,模板化解析器有点失败.Razvan说,这是因为没有跟进语义.
模板化了解析器,但已存在libdparse,所以未提供新东西.有一堆库在不同规模上,做dmd已在做的事情.
沃尔特说他有点喜欢void*方法,这样,编译器可毫不知情地添加勾挂.
Timon问,为什么不直接模板化分析AST族,并让库拥有自己的可勾挂AST.这就不会干扰标准编译编译器.也不会编辑现有的AST节点.
Walter说,如果编译器是适当模块化的,就不必模板化.如果正确封装内容,只需为不同行为导入不同模块即可.
可考虑,看看是否可减少AST节点的导入次数.试使它们更具插件性.因此,与其使用模板等,不如导入带自己功能的不同模块.
有很多方法可完成.
Timon问,如何告诉现有模块,请导入我的模块而不是现有模块.这仍需要模板化.Walter说,你可把你的模块放在不同目录中,并用-I开关给编译器指出来.
然后就有了不同的实现.
拉兹万说,那不再是库了.你必须替换现有文件为你的文件.这不能解决问题.
Walter:所以即它是否应该是已编译的DMD库或源码DMD库.
拉兹万说是的.如果在修改文件,不妨只使用编译器的一个分支.重点是:想与最新编译器同步,且想拥有所有功能,只需插件要用功能即可.
Adam说,不修改文件,而是在构建系统中,完全替换它们.但这是个痛苦.Razvan说,他想尽量重用现有代码,因此,对指定文件,需要大量复制粘贴.
Walter说他理解Razvan说的,但如果更好封装模块,则与编译器的其余部分同步的问题就少得多了.
如,他终于让词法解析器和解析器不再导入编译器的其余部分.现在,你可插件不同的词法解析器和不同的解析器,然后无需更改的使用编译器的其余部分.
为什么不能用AST节点来完成?如果要更改语句节点,只需导入不同的statement.d文件即可.
如果正确封装它,则很容易把编译器的statement.d替换为用户版本.用户可按合适方式调整.
Timon说,根本问题是,如何在许多不同类型的AST节点上重用语义.D文件接口不是好的接口.
也许可结合这两者.
Walter说,已有用dmd的只是简单读取目录中的所有文件,并编译在一起的单个命令,来替换build.d的讨论.
这很有趣,并更容易从dmd源码外构建.他同意build.d的功能太复杂,它应该只是编译文件.
atila说,最好,人们只需在dub.json/sdl中加上dmd一个依赖项,就可工作了.沃尔特同意了.
Martin说,这和之前在前端上放置linter类似.同样,决定在编译器中保留检查无法访问的代码,以便工具可用它.
替换D文件不会削减它.需要介于两者之间的东西.应该有个DMD库基的编译器分支.因此,可在那里做mixin(插件),void*等,以便可用它.
这是有些轻微修改的半开放的前端接口.因此,可添加像void*等修改,或为所有AST节点添加一些额外的状态,访问者或需要的函数,这些功能会有成本,且不想在前端中看到这些功能.
如,如果必须从一些性能关键方法中,删除final属性,以便可像用任意工具一样使用前端,可在分支中这样尝试.并可把DMD库作为GitHub上的一个单独的项目.
可更新每个主要或次要版本,可在此基础上构建工具.这样,就不必在编译器自身中添加所有额外东西,从而变慢或变丑.
类似在LDC使用dmd作为前端.他们重写了单仓库的历史,排除了或移动了一些文件到其他地方,以便可更方便地使用它们,并有些小调整,如增加些字段,替换些函数等.
跟上最新dmd变化还不错.如果由社区团队处理,类似维护配音,这应该很好.
沃尔特说,他很高兴马丁提出了该问题.他突然发现Martin和Iain已在使用dmd作为库,因此他们的经验对如何更好完成它非常有用.
也许更好地支持它们,会更好地支持dmd库.他不知道是如何把它整合到LDC和GDC中的.
马丁说,LDC和GDC显然在修改D的某些部分,至少LDC是这样,但只是很少.对其余接口,是与C++互操作.
Mathias说,这些不是特例,它们是DMD库的用例.马丁答应了,但他没有看到其中的关联.Mathias说,它们是人们需要DMD库的各种功能的好示例.
目前,它们是黑客,因为在LDC版本块中放置它们,并修改代码.但是通过上游化它们,会把黑客变成适当的配置点,这就是重点.
马丁同意了.他的观点是,不想丑化代码,降低运行时和编译器源码的可读性.对检查器或这些计划的扩展点也适合.
因此,可保持前端不变,并修改中间的DMD库,以简化一些勾挂,添加额外状态,如果要替换该功能,可能会替换整个AST.
他继续重申,替换D文件建议,显然不是想要的.与Razvan提出的未用导入示例一样,期望重用大部分功能.
只需更换一个小的搜索功能.因此,DMD库项目作为它自己的小项目开始侵改是相当不错的.可见它是如何演变的.
还有extern(C++)接口,如何影响DMD库的附带讨论.
Steven说,与新Phobos版本讨论类似,即按完全不同的方式编译重用相同代码.
atila
atila说,在DConf之后,他问过Roy是否想为新的共享语义编写规范,但还未收到回复.但应继续下去.
他也一直在思考Robert关于安全代码的建议,他做得越多,意义越大.不必等待版本,这样,可解决DIP1000的所有问题,可能一举解决.
整个问题是,因为要用@safe,不得不到处添加域(scope).它应只适合@trusted.
另一件事是:他一直在思考Timon的想法,即指针有个说明是否是隔离的编译时枚举.想用向量类型和一些分配器来搞个概念证明,看看怎么样.
还会有些如何向语言添加隔离的信息.
还在思考该如何版本化.
丹尼斯认为标准库都会破坏.因此,DIP1000并不是一个重大变化.重大更改是修复了接受无效错误,目前,已允许切片本地静态数组.
罗伯特的提议,严格来说比DIP1000更有破坏性.
阿蒂拉说他理解这一点,但,这段代码显然是错误的.破坏了代码.只是编译器没有告诉你.且DIP1000的问题是采纳.问题是必须到处加域.
如果修复共享或域等会破坏很多代码,难道不应延迟到新版本,而不是默认语言修复?Walter说DIP1000显然必须在一个版本中.
阿蒂拉说:“好吧”.共享不难.代码是完全错误的,不会降级到原子来破坏.沃尔特同意了.
Timon问,该想法是否是在共享变量上原子操作.沃尔特说是的,针对CPU支持的原子操作.如果CPU不支持,则禁止.它因目标而异.
Timon说是的,但原子操作不是唯一同步方法.阿蒂拉说这是真的,但问题是,总有人丢弃共享来选出.
如果打算直接共享,应该把它传递给接受共享的函数,或丢弃掉,并锁定互斥锁,或想要的其他东西.
Timon提到了Manu拒绝所有这些操作.阿蒂拉说这行不通.今年一直在努力修复它,但到处都是漏洞.
Timon问有什么问题.atila说有很多,如:synchronized(mutex)不能使用-preview=nosharedaccess编译,因为你正在访问互斥锁.
运行时不会用它构建,Phobos也不会.他一直在努力堵住漏洞,但发现最好不要这样.相反,需要时,只需降级到原子即可.
如果不编译,就没用.
Walter告诉Timon,问题是不能按参数传递共享值.如果创建了某项内容的共享指针,则因为它是共享的,无法操作它.
如果要访问共享指针,则必须通过std.atomic的引用来传递它.但是,CPU上有原子加载指针类型和其他基本类型的指令.
为什么不利用这一点,当目标CPU可直接支持共享操作时,允许共享操作.
Timon说,似乎总是会同步的.阿蒂拉说,这比现在的世界要好.再说一遍,如果这样,且个人资料显示这是你的问题,请丢弃共享.
Walter说,(如果有CPU指令)可只使用CPU指令时,调用std.atomic函数的效率会降低.Timon说,问题的解决方法似乎是内在(intrinsics)的.
该提案像是内在函数,但语法更好.有些如何同步的决定,这样做时,会锁定默认语法.
原子负载和存储的合理语义可能根据环境.
atila对此表示同意,但一般,这是顺序一致性.
沃尔特说,这与向量指令方面问题相同.如果代码中请求操作存在指令,则编译器为你生成向量指令.如果目标CPU上不存在该指令,则编译器无法编译,你可决定替代路径.
所以,如果编译,就会起作用.如果无法在目标计算机上编译,则必须找出解决方法.
Walter继续说道,如果CPU有原子加载整数的指令,编译器就支持它,它会给你原子加载.如果要编译不支持整数原子负载的CPU,它无法编译.
这正是向量指令的工作方式.在这方面取得了成功.他对此很满意.
他说,迁移到不同平台时,也许共享代码会中断,也许不会.但这是应该的,因为共享与CPU的构造方式隐含在一起.所以这是应该做的.
沃尔特
沃尔特说,已可解决DConf上出现的一堆问题.他对被迫为ImportC使用微软汇编语法,非常失望,因为他们没有提供最终不用内联汇编器版本的头文件的路径.
相关文章:
2311d9月会议
DLF2023年9月月度会议摘要 Robert Robert,在DConf上做了一些初步的JSON5工作.他还更新了Bugzilla到GitHub的迁移脚本.他使用了"隐藏"API,现在脚本要快得多. 除此外,他在DScanner上做了一些小事,并等待JanJurzitza(Webfreak)合并它们.他指出,沃尔特曾要求他写一篇演…...
《算法通关村——二分查找在旋转数字中的应用》
《算法通关村——二分查找在旋转数字中的应用》 这里我们直接通过一个题目,来了解二分查找的应用。 153. 寻找旋转排序数组中的最小值 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如&a…...
C/S架构学习之基于TCP的本地通信(服务器)
基于TCP的本地通信(服务器):创建流程:一、创建字节流式套接字(socket函数): int sock_fd socket(AF_LOCAL,SOCK_STREAM,0);二、创建服务器和客户机的本地网络信息结构体并填充服务器本地网络信…...
乡镇村污水处理智慧水务智能监管平台,助力污水监管智慧化、高效化
一、背景与需求 随着城市化进程的加速,排放的污水量也日益增加,导致水污染严重。深入打好污染防治攻坚战的重要抓手,对于改善城镇人居环境,推进城市治理体系和治理能力现代化,加快生态文明建设,推动高质量…...
OSPF综合
实验拓扑 实验需求: 1 R4为ISP,其上只能配置IP地址; R4与其他所有直连设备间均使用公有IP 2 R3-R5/6/7为MGRE环境,R3为中心站点 ; 3 整个OSPF环境IP基于172.16.0.0/16划分; 4 所有设备均可访问R4的环回; 5 减少LSA的更新量,加快收…...
vue分片上传视频并转换为m3u8文件并播放
开发环境: 基于若依开源框架的前后端分离版本的实践,后端java的springboot,前端若依的vue2,做一个分片上传视频并分段播放的功能,因为是小项目,并没有专门准备文件服务器和CDN服务,后端也是套用…...
【MySQL】对表结构进行增删查改的操作
表的操作 前言正式开始建表查看表show tables;desc xxx;show create table xxx; 修改表修改表名 rename to对表结构进行修改新增一个列 add 对指定列的属性做修改 modify修改列名 change 删除某列 drop 删除表 drop 前言 前一篇讲了库相关的操作,如果你不太懂&…...
Hadoop原理,HDFS架构,MapReduce原理
Hadoop原理,HDFS架构,MapReduce原理 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,…...
【Spring Boot】035-Spring Boot 整合 MyBatis Plus
【Spring Boot】035-Spring Boot 整合 MyBatis Plus 【Spring Boot】010-Spring Boot整合Mybatis https://blog.csdn.net/qq_29689343/article/details/108621835 文章目录 【Spring Boot】035-Spring Boot 整合 MyBatis Plus一、MyBatis Plus 概述1、简介2、特性3、结构图4、相…...
Hafnium之强制性的接口
安全之安全(security)博客目录导读 目录 一、FFA_VERSION 二、FFA_FEATURES 三、FFA_RXTX_MAP/FFA_RXTX_UNMAP 四、FFA_PARTITION_INFO_GET 五、FFA_PARTITION_INFO_GET_REGS...
计算机视觉:使用opencv实现银行卡号识别
1 概述 1.1 opencv介绍 OpenCV是Open Source Computer Vision Library(开源计算机视觉库)的简称,由Intel公司在1999年提出建立,现在由Willow Garage提供运行支持,它是一个高度开源发行的计算机视觉库,可以…...
【Proteus仿真】【Arduino单片机】简易计算器设计
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器,使用PCF8574、LCD1602液晶、4*4矩阵键盘等。 主要功能: 系统运行后,操作矩阵按键可实现简单四则运算。 二、软件设计 /* …...
pychon/PIL/opencv/json学习过程中遇到的问题
1. 使用PIL.Image读取图片 注意:pytorch中对图像预处理是transforms的输入必须是PIL格式的文件,使用cv2读取的图片就按照第二条的代码处理(3通道合并、归一化处理) from PIL import Image img Image.open("test1.jpg"…...
YOLO目标检测——番茄数据集下载分享【含对应voc、coco和yolo三种格式标签】
实际项目应用:番茄检测数据集说明:番茄目标检测数据集,真实场景的高质量图片数据,数据场景丰富标签说明:使用lableimg标注软件标注,标注框质量高,含voc(xml)、coco(json)和yolo(txt)三种格式标签…...
(JAVA)线程
线程的创建 方式一:Thread public class dome {public static void main(String[] args) {MyThread myThread new MyThread();myThread.start();for(int i1;i<5;i){System.out.println("主线程"i);}} }public class MyThread extends Thread{Overri…...
【深度学习环境】windows安装 NVIDIA Docker
摘要 不要安装 Docker Desktop!我们将在 Ubuntu 中自行安装 Docker。 请安装 Windows 10 Insider Build 或 Windows 11 (Beta也行)。(稳定发行版无法在 WSL 2 中使用 GPU) 请安装 WSL 2 w/Ubuntu 20.04 或同等版本。…...
【微信小程序】自定义组件(三)
自定义组件 插槽1、什么是插槽2、单个插槽3、定义多个插槽 父子组件之间的通信1、父子组件之间的通信的3种方式2、事件绑定3、behaviors 插槽 1、什么是插槽 在自定义组件的wxml结构中,可以提供一个<solot> 节点(插槽),用…...
Python语言:经典案例分析讲解2
例题1:文件的操作 例题2:调用函数求偶数之和 例题3:调用函数并使用递归的方法求斐波那契数前N项之和 题1: 以只写的模式打开文件test.txt,写入"Python",关闭文件。 代码如下: f open("E:/…...
dbeaver连接别人的数据库没有表
1.概念 非缺省的数据库: 通常是指在一个数据库管理系统(DBMS)中,除了系统默认创建的数据库之外的其他用户创建或自定义的数据库。许多数据库系统在安装后会创建一个默认数据库,例如MySQL中的mysql数据库,…...
EXIT(1)
EXTI介绍 EXTI是片上外设 NVIC是cpu内的外设 回忆起之前的GPIO和AFIO 我们是如何检测按键按下的 我们是一直用while循环读取IDR寄存器的对应位置的值 一直检测判断按键是否被按下 那么是否有第二种方式检测按键是否被按下了呢? 通过EXTI 当EXTI检测到按键的电平发生…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
