What is the overhead of the fixed statement when used on an unmanaged struct?

左心房为你撑大大i 提交于 2019-12-11 10:29:34

问题


In particular, I'm thinking of a scenario like this:

    unsafe struct Foo
    {
        public int Bar;

        public Foo* GetMyAddr()
        {
            fixed (Foo* addr = &this)
                return addr;
        }
    }

Assuming a Foo stored in unmanaged memory, I'm trying to figure out what is involved in evaluating the fixed statement in GetMyAddr. I know as the programmer that this struct is never on the managed heap, I just need to get it's address in unmanaged memory in the most efficient manner. I'm especially concerned if there's any locking or atomic operations used here as that would make it completely unsuitable.


回答1:


This won't do what you think it will do. The "fixed" statement only pins the managed object (this) for the duration of the "fixed" statement itself, which ends as soon as you "return". See the MSDN docs for the details.

You already say your "Foo" is in unmanaged memory, which means that the managed GC isn't going to be moving it around on you. In that case, can't you just return "&this" directly? Alternatively, you may want to consider taking your unmanaged object and marshalling it into a managed one. Give a little more context around what you're doing and we'll all be able to give more specific advice.




回答2:


The expression &this has no meaning when the structure is present in unmanaged memory. There is no way to allocate it there. A key property of managed structures is that their memory layout is not discoverable and is not compatible with the unmanaged view of that structure. The CLR rearranges fields as it sees fit to get the minimum size while aligning members. It will in fact swap fields if a later one can fit in the padding.

You cannot get past Marshal.PtrToStructure to convert an unmanaged struct to its managed version. Marshal.SizeOf is only accurate for the unmanaged layout.




回答3:


I set up a micro benchmark and measured the overhead of fixed when used on a struct in unmanaged memory, it is very low, returning fixed(this) is only 10 times more expensive than simply returning this. That's acceptable for my use case (hashing using the address of the struct.) I was unable to learn how it was implemented, but it does seem to be fast enough in this case.




回答4:


Basically there's no overhead at all. Fixed means "pin the location the pointer points to in memory, don't relocate it." Every other managed pointer can be "bent" by the Garbage Collector at will if it decides to move memory around. Fixed will prevent this, so basically it will "save" this (possible) overhead.

I don't know about the implementation of fixed pointers, but in the simplest case it's just blacklisting memory blocks. This is not very costly compared to normal managed pointers.

On the other hand, it prevents all sorts of optimazations that the GC might decide to perform in terms of memory management like increasing localization, reducing fragmenation etc.



来源:https://stackoverflow.com/questions/3323042/what-is-the-overhead-of-the-fixed-statement-when-used-on-an-unmanaged-struct

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!