- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类似于下面的函数:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetVariable<T>(T newValue) where T : struct {
// I know by this point that T is blittable (i.e. only unmanaged value types)
// varPtr is a void*, and is where I want to copy newValue to
*varPtr = newValue; // This won't work, but is basically what I want to do
}
我看到了 Marshal.StructureToIntPtr(),但它似乎很慢,而且这是对性能敏感的代码。如果我知道 T
类型,我可以将 varPtr
声明为 T*
,但是...嗯,我不知道。
无论哪种方式,我都在寻求最快的方法来做到这一点。 “安全”不是问题:到代码中的这一点,我知道结构 T
的大小将完全适合 varPtr
指向的内存。
最佳答案
一个答案是在 C# 中重新实现 native memcpy,利用 native memcpy 尝试执行的相同优化技巧。你可以看到微软在他们自己的源代码中这样做。查看Buffer.cs Microsoft 引用源中的文件:
// This is tricky to get right AND fast, so lets make it useful for the whole Fx.
// E.g. System.Runtime.WindowsRuntime!WindowsRuntimeBufferExtensions.MemCopy uses it.
internal unsafe static void Memcpy(byte* dest, byte* src, int len) {
// This is portable version of memcpy. It mirrors what the hand optimized assembly versions of memcpy typically do.
// Ideally, we would just use the cpblk IL instruction here. Unfortunately, cpblk IL instruction is not as efficient as
// possible yet and so we have this implementation here for now.
switch (len)
{
case 0:
return;
case 1:
*dest = *src;
return;
case 2:
*(short *)dest = *(short *)src;
return;
case 3:
*(short *)dest = *(short *)src;
*(dest + 2) = *(src + 2);
return;
case 4:
*(int *)dest = *(int *)src;
return;
...
有趣的是,他们 native 实现了最大 512 的所有大小的 memcpy;大多数大小都使用指针别名技巧来让 VM 发出对不同大小进行操作的指令。只有在 512,他们才最终开始调用 native memcpy:
// P/Invoke into the native version for large lengths
if (len >= 512)
{
_Memcpy(dest, src, len);
return;
}
据推测,原生 memcpy 甚至更快,因为它可以手动优化以使用 SSE/MMX 指令执行复制。
关于c# - 将 blittable 结构复制到非托管内存位置的最快方法 (IntPtr),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24619472/
我有这个结构和这段代码: [StructLayout(LayoutKind.Sequential, Pack = 8)] private class xvid_image_t { [Marsh
我正在努力确保我的托管到非托管调用得到优化。有没有一种快速的方法可以通过查看 IL 来查看是否有任何非 blittable 类型不小心进入了我的 pinvoke 调用? 我尝试在 .dll 中编写两个
这里是 blittable 的列表 types .它包含 Int32 和 Int64。但我在列表中看到的不仅仅是普通的“int”。 C# 如何处理普通的“int”类型?根据系统的不同,它是否会被替换为
我有一个函数 foo,它采用非托管类型,然后我创建了一个通用结构,它要求类型参数是非托管的: [] type Vector4 = val x : 'T val y : 'T v
我正在尝试使用 here 中描述的 ReadUsingPointer 方法拥有一个用于大型二进制文件的光速二进制阅读器。 但是,我试图传递给它的结构包含字符串。我想知道如何规避这一点并避免“无法获取托
在我的序列化器/反序列化器中,我有以下片段: if (element_type.IsValueType && collection_type.IsArray) { tr
假设你有一个 Array array; 假设: 这个数组的类型是blittable 数组可能有一个任意数的维度(1..N) 在编译时未知 基于这些假设,我相信我们可以假设 .Net 框架将其内容存储在
我有一个类似于下面的函数: [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetVariable(T newValue)
GCHandle.Alloc 拒绝用包含“十进制”数据类型的结构固定数组,但同时可以很好地处理“ double ”。这是什么原因,我可以通过某种方式解决它吗? 我知道我可以改用 unsafe/fixe
我想知道 C# 7.3's Unmanaged type constraint提供语言支持以强制类型可 blittable。根据Blittable and Non-Blittable types正确地
我正在重写我公司在 C# 和 C++ 之间接口(interface)的库代码中过度设计且无法维护的部分。我已经开始研究 P/Invoke,但似乎没有多少可用的帮助。 我们将包含各种参数和设置的结构传递
我尝试在我的 C# 代码中使用 C++ DLL。 所有读取的数据都必须作为指向结构的指针传递给 dll。我的第一个想法是只保留一些非托管内存,将指针传递给函数,然后提取数据。问题是这些函数只会返回一个
public class TestSerializer { public static byte[] StructureToByteArray(Test[] array) {
我有一个关于将 C++ 数组编码到 C# 的问题。double* 会自动转换为 double[] 吗? 我知道 double 是一种 blittable 类型,因此 C++ 中的 double 与 C
Trying to use the UnmanagedCallersOnly attribute but I'm stuck on some string fields in the struc
我是一名优秀的程序员,十分优秀!