pin_ptr 相对于本机 (VC) 堆对象的性能
在 C# 到本机 lib CLI/C++ 包装器中,我有一个选择:
- 将本机指针存储在托管类中(本机对象是使用本机“new”创建的)
或
- 将本机对象作为数据 blob 存储在托管类的字段中,以及在每次本机使用之前使用
pin_ptr
将其固定。
有人对这两条路径的相对性能成本进行过比较分析吗?
谢谢!
In a C# to native lib CLI/C++ wrapper, I have a choice:
- Store native pointer in a managed class (native object is created using native "new")
or
- Store native object as a data blob in a managed class' field, and use
pin_ptr
to pin it before each native use.
Has anyone done any comparative analysis on the relative performance costs of the two paths?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
pin_ptr 是为了防止托管堆上的对象在其地址传递给不知道椅子可能被 GC 拉动的本机函数时被 GC 移动。它不会影响本机堆或堆栈上分配的内存。
将本机对象作为 blob 存储在托管类中是托管 C++ 对混合类型所做的事情。返回指向未固定的垃圾收集堆上的内存的指针太容易了,并且可能会在以后使应用程序崩溃,而且这个问题太难调试了。这个问题是如此普遍(人们不希望椅子可以被 GC 拉走),以至于微软决定完全禁用混合类型,这样人们就必须明确指定对象的内存在哪里。
pin_ptr is to prevent objects on the managed heap from being moved by the GC when its address is being passed to native function functions who aren't aware the chair could be pulled by the GC. It does not affect memory allocated on the native heap or on the stack.
Storing native object as blob in a managed class is what managed C++ did for mixed types. It was too easy to returns a pointer to memory on the garbage collected heap that is not pinned and could crash the app later on, and this problem is too hard to debug. This problem is so common (people do not expect the chair can be pulled by GC) that Microsoft decided to disable mixed type altogether so people have to explicitly specify where the object's memory is.
可能没有太大区别。 GC 分配实际上比原生
new
稍快。如果在 GC 进行收集时固定对象,那么固定只是一个性能问题。如果托管对象最终足够大,可以进入 LOH,则固定是免费的。但我自己没有测量过。
我不会做的是使用 GCHandle 在函数调用之间保持对象固定。这比
pin_ptr
的设置成本更高,并且更有可能影响 GC。对于需要永久保留在适当位置的数据,请使用本机分配器。There's probably not much difference. GC allocation is actually slightly faster than native
new
. And pinning is only a performance problem if the object is pinned when the GC does a collection. If the managed object ends up big enough to go into the LOH, then pinning is free.But I haven't measured it myself.
What I wouldn't do is use a GCHandle to keep the object pinned between function calls. That's more expensive to set up than a
pin_ptr
and more likely to impact the GC. For data that needs to stay permanently in place, use the native allocator.