我不习惯用指针代码(例如C++),也有不安全的岛屿:只有"安全"的C#.现在我想在.Net Micro Framework的C#中实现一个函数,其中紧凑性和性能非常重要.基本上,我会收集4个短裤,从而填充缓冲区(例如字节数组).让我们说每个样本都是这样的:
struct MyStruct
{
public short An1;
public short An2;
public short An3;
public short An4;
}
Run Code Online (Sandbox Code Playgroud)
每个样本都是通过计时器事件收集的,因此我无法循环(有几个原因).我已经尝试了很多方法来有效地做到这一点,但表现最好的似乎是这一个:
unsafe struct MyStruct2
{
public fixed byte Buffer[Program.BufferSize];
}
unsafe class Program
{
public const int BufferSize = 0x1000;
public const int ArraySize = BufferSize / 8;
static MyStruct2 _struct2 = new MyStruct2();
static MyStruct* _structPtr;
unsafe static void Main(string[] args)
{
int iter = 5000; //just for simulate many cycles
for (int i = 0; i < iter; i++)
{
//let's make a trick!
fixed (byte* ptr = _struct2.Buffer)
_structPtr = (MyStruct*)ptr;
_structIndex = 0;
do
{
Test5();
} while (++_structIndex < ArraySize);
}
Console.ReadKey();
}
unsafe static void Test5()
{
_structPtr->An1 = (short)An1();
_structPtr->An2 = (short)An2();
_structPtr->An3 = (short)An3();
_structPtr->An4 = (short)An4();
_structPtr++;
}
//simulations of ADC reading
static int An1()
{
return 0x1111;
}
static int An2()
{
return 0x2222;
}
static int An3()
{
return 0x3333;
}
static int An4()
{
return 0x4444;
}
}
Run Code Online (Sandbox Code Playgroud)
对以下更安全的方式的改进 - 例如 - 不是那么高(177ms对224ms),但无论如何它都很重要.
static MyStruct Test3()
{
var data = new MyStruct();
data.An1 = (short)An1();
data.An2 = (short)An2();
data.An3 = (short)An3();
data.An4 = (short)An4();
return data;
}
Run Code Online (Sandbox Code Playgroud)
注意:我已经删除了一些代码,但我认为它已经足够清楚了.
我的问题是:我通过将"固定"指针复制到另一个未固定的"技巧"可能是否可靠?...但是你可以假设所有数据都是静态分配的,所以应该固定.先感谢您.干杯
我认为该代码不安全。在固定范围内之后_structPtr = (MyStruct*)ptr
,您可以假设 _struct2 不会移动,然后继续将数据放入 _structPtr 中。虽然您认为它不会被 GC 是正确的,但这并不意味着 GC 在内存压缩期间不会移动它。.NET Compact Framework 仍然进行垃圾收集,我认为它会压缩内存而不是使其碎片化。
例如,如果在 _struct2 之前在堆上分配的瞬态(非静态)对象被 GC 删除,则该结构使用的内存可能会转移到该瞬态对象使用的空闲空间中。此时 _structPtr 指向未使用的内存。
修改 Test3() 会有帮助吗ref MyStruct data
?
此外,签出[StructLayout(LayoutKind.Explicit)]
和[FieldOffset(...)]
它将允许您拥有一个具有多种访问其中相同数据的方式的结构。在您的情况下,可以是 4 个字节或 1 个 int 或(可能)1 个 4 字节数组。
归档时间: |
|
查看次数: |
3747 次 |
最近记录: |