gpt4 book ai didi

.net - MSIL中Cpblk操作码的完整语义

转载 作者:行者123 更新时间:2023-12-04 22:50:31 27 4
gpt4 key购买 nike

The MSDN documentation对于 cpblk有点稀疏:

The cpblk instruction copies a number (type unsigned int32) of bytes from a source address (of type *, native int, or &) to a destination address (of type *, native int, or &). The behavior of cpblk is unspecified if the source and destination areas overlap.

cpblk assumes that both the source and destination addressed are aligned to the natural size of the machine. The cpblk instruction can be immediately preceded by theunaligned. instruction to indicate that either the source or the destination is unaligned.


好的,与其他批量复制操作(例如 Array.Copy)相比, Marshal.Copy , 和 Buffer.BlockCopy , 我们知道:
  • 大小以字节为单位
  • 指针应对齐

  • 这给我留下了一些问题:
  • 应该先固定缓冲区吗?操作数类型是否为 native int 是否重要? 、“非托管指针”还是“托管指针 (&)”?
  • 类型有限制吗? (例如,Buffer.BlockCopy 仅适用于原始类型,而不适用于结构,即使它们仅包含原始类型)

  • 根据 https://stackoverflow.com/a/26380105/103167固定是不必要的,但支持的解释是错误的。 (我怀疑这是由于大对象堆没有被压缩这一事实的过度概括)
    ECMA-335 也不是很有帮助。那里的指令描述包含相同的措辞并添加

    [Rationale: cpblk is intended for copying structures (rather than arbitrary byte-runs). All such structures, allocated by the CLI, are naturally aligned for the current platform. Therefore, there is no need for the compiler that generates cpblk instructions to be aware of whether the code will eventually execute on a 32-bit or 64-bit platform. end rationale]


    好的,这听起来应该接受比 Buffer.BlockCopy 更多的类型.但仍然不是任意类型。
    也许新发布的 .NET Core 源代码会给出一些答案。

    最佳答案

    cpblk及其伴侣,initblk , 直接映射到任何本地语言编译器用来初始化和复制结构的内在函数。无需等待 .NETCore 源码,您可以从 SSCLI20、clr/src/fjit/fjitdef.h 中看到它们的语义。一个简单的抖动,它转换为 cpblk直接调用memcpy() , initblkmemset() . C 编译器使用的相同内在函数。

    当然不考虑 GC,C# 和 VB.NET 编译器根本不使用这些操作码。但是 C++/CLI 编译器可以,一个简单的例子:

    using namespace System;

    struct s { int a; int b; };

    int main(array<System::String ^> ^args)
    {
    s var = {}; // initblk
    s cpy = var; // cpblk
    return 0;
    }

    优化的 MSIL:
    .method assembly static int32  main(string[] args) cil managed
    {
    // Code size 34 (0x22)
    .maxstack 3
    .locals ([0] valuetype s cpy,
    [1] valuetype s var)
    IL_0000: ldloca.s var
    IL_0002: ldc.i4.0
    IL_0003: ldc.i4.8
    IL_0004: initblk
    IL_0006: ldloca.s cpy
    IL_0008: ldloca.s var
    IL_000a: ldc.i4.8
    IL_000b: cpblk
    ...
    }

    当前的 .NET 抖动生成内联代码,对小型结构使用简单的寄存器移动,对大型结构使用 REP STOS/MOVS。非常类似于 Buffer.Memcpy() 所做的。

    关于.net - MSIL中Cpblk操作码的完整语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27279668/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com