c# - C# 结构体参数和局部变量默认对齐吗?

标签 c# simd memory-alignment

假设我有一个如下定义的结构:

[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 1)]
readonly struct Example {
    [FieldOffset(0)]
    public float A;
    [FieldOffset(4)]
    public float B;
    [FieldOffset(8)]
    public float C;
    [FieldOffset(12)]
    public float D;
}

Example 的本地实例和参数实例是否保证 16 字节对齐?

具体来说,我很好奇是否可以使用 Unsafe.As 将这样的结构重新解释为 Vector4:

static void Test(Example e) {
    var vec4 = Unsafe.As<Example, Vector4>(ref e); // Is vec4 aligned?

    var e2 = new Example();
    vec4 = Unsafe.As<Example, Vector4>(ref e2); // Is vec4 aligned?
}

最佳答案

结构类型的局部变量和参数不一定是“过度对齐”(即与标量代码所需的任何内容对齐)。 Example 不需要 16 对齐,因此 JIT 编译器没有特定的动机来确保它得到它,当然它可能会发生,我必须稍微修改一下源代码得到一个未对齐的地址(好吧,不是 16 对齐,从标量的角度来看它仍然足够对齐)。

下面是实际中实际未进行 16 对齐的屏幕截图:

Debugger showing an address of 000000D29C57E6F8

为了实现这一点,我在 e 之前插入了另一个结构参数,其大小为 8。

之所以存在冗余移动,是因为这种情况发生在未优化模式下(模块加载时抑制 JIT 优化,这是调试的默认设置,但可以将其关闭以调试优化代码,这有其自身的问题)。

但是,显然,Unsafe.As 产生的负载是未对齐的负载(vmovupd,理论上,这是加载 2 个 double 向量而不是 4 个 double 向量的指令) float ,但这没有实际区别),因此未对准不会导致异常。我找不到明确的文档来说明以这种方式加载 Vector4 需要哪种对齐方式。

关于c# - C# 结构体参数和局部变量默认对齐吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77062415/

相关文章:

c++ - 使用SIMD指令的平行二项式系数

assembly - 如何修复 "ld: warning: arm64 function not 4-byte aligned"警告?

c# - 不显示 Mono Linux 上的 Latin-1 非 ASCII 符号

c# - 从包含通用 O​​bservableCollection 的类型 (System.type) 中获取字符串 "System.Collections.ObjectModel.ObservableCollection"?

c# - OData over Web API - 如何查询嵌套属性?

Objective-C 运行时 : What to put for size & alignment for class_addIvar?

c - 多个数据类型的单个 malloc

c# - 如何在 LINQ 中加入未知数量的列表

c - 使用 SSE 实现高斯消元

c++ - 是否可以使用 d[x] 寄存器中的值作为 vld 中的地址?