gpt4 book ai didi

c# - 如何在 C# 中对齐 float 组?

转载 作者:行者123 更新时间:2023-11-30 17:48:22 24 4
gpt4 key购买 nike

我想在 C# 中将 float 组对齐到 16 字节边界。

我知道的一种技术是固定阵列: http://meekmaak.blogspot.ca/2010/06/c-memory-aligned-array-wrapper-for-fast.html

我不喜欢固定内存的想法。我担心它会如何影响垃圾收集的性能。

还有其他技术吗?我正在考虑创建一个 16 字节的结构,为其分配一个数组,然后将该数组转换为一个 float 数组。

[StructLayout(LayoutKind.Explicit)]
public struct Float4 {
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
[FieldOffset(12)] public float W;
}

我不确定接下来要做什么(在不同类型的数组之间进行转换)以及最佳方法是什么?

最佳答案

根据您的操作,使用具有显式布局的结构可能有意义,该结构至少包含一个 longdouble 并覆盖您的 float 变量(我认为验证器会允许这样做,但我不确定)或使用一些手动管理的内存。一个包含超过 22,000 个 float 的数组将被分配到大对象堆上;我认为包含 IIRC 2,000 的数组也将同样对齐,但我不知道这种处理是否适用于 64 位系统,或者它是否适用于包含 double 的结构数组。如果您的数组不够大,无法“属于”大对象堆,您可能需要分配一个大数组并手动将其中的部分子分配给不同的消费者。

在某些版本的 .NET 上,可能已经可以分配一个包含三个额外元素的数组,并使用一个 DLL,该 DLL 通过引用接受一个 float,报告其地址的第 2-3 位,和 shift 在数组中 float 以确保正确对齐(例如,如果您想要一个包含 256 个值的数组,分配 259,并且如果 DLL 报告 arr[0] 位于地址 0x12345ABC,则使用数组槽#1-#256)。这种方法的困难在于 GC 可能会时不时随意移动一些东西,因此可能不得不周期性地向上或向下移动数组中的元素以更正它们的对齐方式。此外,我不知道是否有可能强制编码器执行真正的“按引用传递”,而不是替换“按值传递结果”[后者传递临时缓冲区的地址,而不是比数组元素]。据我了解,某些版本的 .NET 很容易进行这种替换。

我个人对为什么 .NET 没有做出重大努力来使大多数对象与缓存行对齐感到有些困惑。盲目地将对象填充到下一个 16 字节的倍数最多会浪费额外 60% 的空间(最坏的情况是将 20 字节的对象填充到 32);为 12、20 和 24 字节的对象添加一些特殊情况的逻辑可以将最坏情况下的开销减少到 14%。由于大多数对象的使用都是在访问它们的类型引用之前进行的,因此在同一缓存行中包含字段数据的前几个字节似乎是性能上的胜利。

关于c# - 如何在 C# 中对齐 float 组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23197817/

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