将 blittable 结构复制到非托管内存位置的最快方法 (IntPtr)

2024-04-03

我有一个类似于以下的功能:

[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 as a T*,但是……嗯,我不这么认为。

不管怎样,我都在寻找最快的方法来做到这一点。 “安全”不是一个问题:在代码中,我知道结构的大小T将完全适合指向的内存varPtr.


一种答案是使用本机 memcpy 尝试执行的相同优化技巧,在 C# 中重新实现本机 memcpy。您可以在 Microsoft 自己的源代码中看到 Microsoft 这样做。请参阅缓冲区.cs http://referencesource.microsoft.com/mscorlib/system/buffer.cs.html#0d691e54a9fdddc3Microsoft 参考源中的文件:

     // 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;
        ...

有趣的是,他们本机实现了最大 512 的所有大小的 memcpy;大多数大小都使用指针别名技巧来让虚拟机发出对不同大小进行操作的指令。仅在 512 处,他们才最终调用本机 memcpy:

        // P/Invoke into the native version for large lengths
        if (len >= 512)
        {
            _Memcpy(dest, src, len);
            return;
        }

据推测,本机 memcpy 甚至更快,因为它可以手动优化以使用 SSE/MMX 指令来执行复制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 blittable 结构复制到非托管内存位置的最快方法 (IntPtr) 的相关文章

随机推荐

  • FFMPEG:合并音频(.mp3)和单个图像将它们转换为视频

    我想合并 IMAGE AUDIO 并使用 FFMPEG 库将它们转换为视频 我成功编译了该库 并得到了 libfmpeg so 但是通过 java 代码执行 ffmpeg 命令时出现问题 这是我正在使用的命令 ffmpeg i image8
  • PHP 中多行注释内的多行注释

    PHP 返回 语法错误 这是否是使用多行注释的完全错误的方法 有时我需要注释掉一大块代码进行测试 而这个代码块包含数百行 并且里面有很多多行注释 注释掉这个大块的最佳方法是什么 除了暂时从文件中删除它之外 来自PHP手册 http php
  • XML 与逗号分隔的文本文件

    好吧 我读了几本关于 XML 的书 并编写了程序来吐出它 等等 但问题是这样的 逗号分隔文件和 XML 文件都是 人类可读的 但总的来说 逗号分隔文件比 XML 文件更容易被我看到 标签通常占用与数据一样多的空间 甚至更多 这似乎掩盖了我正
  • argc、argv、envp的内存布局

    据我了解 环境变量的值直接在内存中以 NULL 结尾argv价值观 除了环境变量之外 auxv存在 环境变量到底是如何布局的 这个布局在哪里指定 记录 以及它适用于哪些系统 一个简单的答案是 程序调用时堆栈的布局由二进制格式定义 例如 EL
  • iPhone Xcode 项目文件夹中是否存储了任何“敏感”内容?

    我想开源我的一个 iPhone 应用程序 我已经在 iTunes 商店中发布 但我显然不想暴露任何 敏感 内容 例如配置证书和代码签名密钥等 我猜那东西只是引用的从 Xcode 项目文件夹 实际上存储在磁盘上其他地方的我的钥匙串中 如果我要
  • 当我添加点击事件时,我的 javascript 函数会重复运行(?)

    免责声明 我正在尝试学习javascript 我不是一个聪明人 所以 我做了一个 Jquery 图像滑块 我很自豪 有用 它加载图像 并日复一日地逐个显示它们 生活过得很好 然后我想为滑块添加导航 黑暗降临在我的小王国上 当我单击其中一个按
  • 保存附件时排除图像 png 和 gif 的 VBA 代码

    我正在使用宏来回复附件 但它总是获取嵌入在邮件中的所有图像并将它们作为附件 我试图在将附件下载到临时文件夹时插入一个片段以排除所有 png 和 gif 格式 原始代码 工作 但也下载嵌入图像 Sub ReplyWithAttachments
  • 哈斯克尔“点黑客”

    In the 数独解决方案的 Wiki 页面 http www haskell org haskellwiki Sudoku Chaining style Solver 一种解决方案声称使用 Dot Hack 链接的 Github 页面不再
  • Windows 8 上的 Firefox 远程调试“意外错误”

    我需要在 Firefox 中调试 Android 的 Web 应用程序 我尝试将设备连接到桌面版 Firefox 但总是收到错误 意外错误 我已经执行了所有步骤https developer mozilla org en US docs T
  • 解析没有完整路径的json

    我想解析 json 而不输入它的路径 I have 如何从未转义的 Url 中获取字符串 我怎样才能在没有路径的情况下做到这一点 所以我有那些 和 我该如何使用它 我的代码是 string itemname Hat with no name
  • 如何在 PHP 中用字符串回显警报——单引号和双引号的一些混淆

    我对如何在屏幕上表示输出 echo 语句中的字符串来调试 php 感到完全困惑 首先 这对我来说实际上很完美 echo 这使用双引号作为 echo 语句的一部分 可以这么说 在命令的外部 并在警报语句上使用单引号 它有效 那么如何在警报语句
  • 没有jquery的outerWidth

    可以使用dom获取元素outerWidth吗 Ej var width document getElementById myDiv outerWidth 不 但是您可以获得 offsetWidth 这可能就是您想要的 From http w
  • linux c - 获取服务器主机名?

    有谁知道有一个函数可以获取linux服务器的主机名吗 我真的不想包含任何标头或编译其他库 希望有一个默认内置的函数 我是 c 新手 like 获取主机名 http linux die net man 2 gethostname 这是运行您的
  • 一个恶意链接仍然反映在网站上

    我的网站是一个静态html网站 没有cms 没有wordpress https www reternetics com https www reternetics com 我运行谷歌广告已经有一段时间了 但现在他们拒绝了我的广告 他们说 该
  • 如何使用 Swift 获取 iOS APP 存档日期 [重复]

    这个问题在这里已经有答案了 我的应用程序有一个要求 我需要使用 swift 显示 ipa 文件创建日期 谁能告诉我该怎么做 提前致谢 您可以使用 Bundle 属性获取应用程序的 url可执行文件URL https developer ap
  • 在mvc c#环境中将doc转换为pdf

    您好 我有一个在特定用户 app pool 用户 下运行的 C MVC 应用程序 我需要将 doc 或 docx 文件转换为 pdf 我认为一个不错的选择是使用 libreoffice 来启动一个启动此进程的进程 为了让自己的生活更轻松 如
  • mat-select 和 mat-chip 可以一起使用吗?

    我想知道是否可以 混合 mat select and mat chip list 在里面chip list 我想显示从中选择的选项mat select 如果是的话我该怎么办 对的 这是可能的 你需要使用
  • 使用 php 将数组分成块并按块在新行中显示结果

    所以正如标题所说 我有一个数组 array 0 gt a 1 gt b 2 gt c 3 gt d 4 gt e 5 gt f 我想做的是循环遍历并分块结果并像这样打印它们 ab cd ef OR abc def 到目前为止我得到了这个 我
  • 如何动态启用禁用的复选框?

    请看这里 http jsfiddle net nShQs http jsfiddle net nShQs 按禁用按钮 然后按启用按钮 该复选框未启用 HTML
  • 将 blittable 结构复制到非托管内存位置的最快方法 (IntPtr)

    我有一个类似于以下的功能 MethodImpl MethodImplOptions AggressiveInlining public void SetVariable