百科问答小站 logo
百科问答小站 font logo



为什么微软建议超过64字节不要使用结构? 第1页

  

user avatar   peng-fei-29 网友的相关建议: 
      

针对这个“64字节”的细节更新一下答案。

如果这个建议是针对2016年以后的.NET Framework(64-bit) 和.NET Core,那么原因是因为RyuJIT 编译器对struct promotion 优化(其他编译器叫做scalar replacement)有64-byte 的struct 尺寸限制。即64-byte 以上的未逃逸struct 不会被拆包并直接计算它的每个field。struct promotion 是.NET 中非常重要的一项优化,因为RyuJIT 的SSA 只针对local variables,struct/class objects 上的冗余操作无法被直接优化掉,比如临时struct object 经常会产生大量memory copy。然而如果一个struct 被promoted 了,那编译器会打开这个struct 并将每一个field 视为local variable 进行优化。

上个月我已经把这个限制放宽到了128-byte Improve struct promotion for 256-bit SIMD fields by fiigii · Pull Request #19663 · dotnet/coreclr

=====================

因为C# 的struct 是value type。

微软设计struct 的一个原因就是要赋予程序员精确控制内存的能力,比如让有能力的开发者把value types 保持在stack 上来避免一些GC 开销。然而由于value type 的特性(比如call-by-value,捕获变量要copy到GC heap 上去,等等),很多时候总是没办法避免copy 整个struct的,比如虽然在函数间传递大尺寸struct 时并不是“直接”copy 整个struct,而是传递一个hidden return buffer 的指针,但你一旦不小心改变了struct 的一部分值,编译器就必须帮你copy 整个struct 来保证call-by-value 的语义。所以用struct 来提升性能时必须是struct 的copy 开销要小于对应class 的GC 开销才行,越大的struct 当然copy 开销也就越大。

性能分析这种事对于一般的开发者要求还是太高了,所以微软直接给出给出一个建议让你记住就行了。我觉得靠谱。(对于不满足于这个level的人,可配合profiling参考 @赵劼 姐夫的答案)

再者为什么是“64 byte”这个数值,我只能猜了,一个很有可能的原因是在目前的CPU 体系结构下很难对64 byte (512 bit)以上的struct 做类似HVA/HFA 的first-class struct 优化,这种优化就是把一个普通struct 当作SIMD type 在SIMD register (xmm, ymm, 或zmm)中传递/拷贝/计算,从而尽量避免内存访问。


user avatar   jeffz 网友的相关建议: 
      

因为值类型传递时是要复制一份的,复制太多性能差。

当然,规则不要硬记,用对以后使用大值类型提高性能也很正常,例如我的项目里就有两百多个字段的值类型,然后开一个大数组,反复复用,于是内存里只有一个大对象,不会回收不回移动,对GC毫无压力。

你问大结构传参怎么办,ref了解一下。事实上因为这种模式对于性能优化太常见,C# 7还提供了readonly ref和ref return和ref local更进一步鼓励人们使用这种模式。




  

相关话题

  .NET类库中HashCodeHelper的实现原理是什么? 
  为什么 C#/.Net在国内的人气远不如国外? 
  C#是如何做到闪电编译时? 
  如何看待关于“数据结构与算法基础”的重要性? 
  C#/JavaList自定义索引? 
  请各位前辈指导下简练代码的思路? 
  c#多播或event监听太多后gc和时间都会爆炸,那么比起List<Action>存在的意义是什么? 
  网游通信协议如何防止封包篡改? 
  你见过哪些令你瞠目结舌的C#代码? 
  C#(csharp)这门语言的优势在哪? 

前一个讨论
如何评价倪光南院士称,微软放任盗版让国产软件起不来?
下一个讨论
各位有什么超实用的生活小窍门呢?





© 2024-11-25 - tinynew.org. All Rights Reserved.
© 2024-11-25 - tinynew.org. 保留所有权利