c#中共享类的内存对齐?(顺便说一下,这是指32位操作系统)一些更新:有没有办法记住c#中对齐类的分配?下面演示了(我认为!)没有正确对齐的双重错误。它对存储在类中的double进行一些简单的数学计算,每次运行计时,对一个变量运行5次定时运行,然后分配一个新变量并重新执行。基本上事实证明你要么有快速、中等或慢速的内存位置(在我的旧处理器上,它们最终分别运行大约40、80或120毫秒)我已经尝试使用StructLayoutAttribute但没有快乐-也许其他事情正在发生?类示例{类变量{公共双值;}staticvoidMain(){constintCOUNT=10000000;while(true){varx=newVariable();for(intinner=0;inner<5;++inner){//将分配移动到此处以更频繁地分配,因此更有可能获得50倍的减速问题varstopwatch=Stopwatch.StartNew();总变量=0.0;for(inti=1;i1)thrownewApplicationException(total.ToString());Console.Write("{0},",秒表.ElapsedMilliseconds);}控制台.WriteLine();所以我看到很多关于互操作结构对齐的网页,类对齐呢?(或者我的假设是错误的,上面还有另一个问题?)谢谢,保罗。有趣的是看着运行机器的齿轮。我有一个问题解释为什么当double只能以两种方式对齐时会有多个不同的值(我得到4)。我认为与CPU缓存行的对齐也起到了一定的作用,尽管这只会增加3个可能的时序。嗯,对此你无能为力,CLR只保证4字节值的对齐,以保证32位机器上的primefaces更新。这不仅仅是托管代码的问题,C/C++也有这个问题。看起来芯片制造商需要解决这个问题。如果它很关键,那么您可以使用Marshal.AllocCoTaskMem()分配非托管内存并使用可以很好对齐的不安全指针。如果为使用SIMD指令的代码分配内存,则必须执行相同的操作,它们需要16字节对齐。考虑绝望移动。为了证明.NET中堆上对象未对齐的概念,您可以运行以下代码,您将看到它现在总是运行得很快。请不要开枪,这只是一个PoC,但如果你真的关心性能,你可以考虑使用它;)publicstaticclassAlignedNew{publicstaticTNew()whereT:new(){LinkedListcandidates=new链表();IntPtr指针=IntPtr.Zero;布尔继续_=真;intsize=Marshal.SizeOf(typeof(T))%8;while(continue_){if(size==0){objectgap=newobject();}candidates.AddLast(newT());GCHandlehandle=GCHandle.Alloc(candidates.Last.Value,GCHandleType.Pinned);pointer=handle.AddrOfPinnedObject();continue_=(pointer.ToInt64()%8)!=0||(pointer.ToInt64()%64)==24;handle.Free();if(!continue_)returncandidates.Last.Value;}返回默认值(T);}}classProgram{[StructLayoutAttribute(LayoutKind.Sequential)]publicclassVariable{publicdoubleValue;}staticvoidMain(){constintCOUNT=10000000;while(true){varx=AlignedNew.New();for(intinner=0;inner1)thrownewApplicationException(total.ToString());Console.Write("{0},",秒表.ElapsedMilliseconds);}控制台.WriteLine();}}}也许StructLayoutAttribute就是您要找的东西?使用struct而不是class,使时间常数也可以考虑使用StructLayoutAttribute。它有助于指定结构的精确内存布局。对于CLASSES,我认为您不能保证它们是如何放置在内存中的。它将正确对齐,否则您将在x64上得到对齐异常。我不知道你的代码片段显示了什么,但我不会说任何与之相符的东西。您无法控制.NET如何将您的类放置在内存中。正如其他人所说,StructLayoutAttribute可用于强制结构的特定内存布局,但请注意,这是为C/C++互操作而设计的,而不是试图微调.NET应用程序的性能。如果您担心内存对齐问题,那么C#可能是错误的语言选择。编辑——打开WinDbg并查看在32位Vista和.NET2.0上运行上述代码的堆。注意:我没有得到上面显示的时间变化。0:003>!dumpheap-typeSample+VariableAddressMTSize01dc2fec003f3c481601dc54a4003f3c481601dc58b0003f3c481601dc5cbc003f3c481601dc60c8003f3c481601dc64d4003f3c481601dc68e0003f3c481601dc6cd8003f3c481601dc70e4003f3c481601dc74f0003f3c481601dc78e4003f3c481601dc7cf0003f3c481601dc80fc003f3c481601dc8508003f3c481601dc8914003f3c481601dc8d20003f3c481601dc912c003f3c481601dc9538003f3c4816total18objectsStatistics:MTCountTotalSizeClassName003f3c4818288TestConsoleApplication.Sample+VariableTotal18objects0:003>!do01dc9538Name:TestConsoleApplication.Sample+VariableMethodTable:003f3c48EEClass:003f15d0Size:16(0x10)bytes(D:testcodeTestConsoleApplicationbinDebugTestConsoleApplication.exe)Fields:MTFieldOffsetTypeVTAttrValueName6f5746e440000014System.Double1instance1655149.00在我0000值看错了,不然类的分配地址好像对齐了?以上就是C#学习教程:c#中类的内存对齐?分享的所有内容,如果对大家有用又需要了解更多C#学习教程,希望大家多多指教转载请多多关注——本文摘自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
