我在C#中有一个uint类型数组,在检查程序是否在小端机器上运行之后,我想将数据转换为big-endian类型。因为数据量可能变得非常大但总是均匀,我想考虑将两种uint类型作为ulong类型,以获得更好的性能并在ASM中对其进行编程,因此我搜索的速度非常快(如果可能的话,速度最快) )汇编程序算法,用于转换big-endian中的little-endian。
答案 0 :(得分:6)
对于大量数据,bswap
指令(在_byteswap_ushort
, _byteswap_ulong
, and _byteswap_uint64
内在函数下的Visual C ++中可用)是可行的方法。这甚至会超过手写组装。没有P / Invoke的纯C#中没有这些,所以:
答案 1 :(得分:2)
您可能只想重新考虑问题,这不应该成为瓶颈。采用天真的算法(用CLI汇编编写,只是为了好玩)。假设我们想要的数字是本地数字0
LDLOC 0
SHL 24
LDLOC 0
LDC.i4 0x0000ff00
SHL 8
OR
LDLOC 0
LDC.i4 0x00ff0000
SHL.UN 8
OR
LDLOC 0
SHL.UN 24
OR
每个数字最多只有13(x86)个汇编指令(通过使用聪明的寄存器,解释器很可能更智能)。它并没有比那更天真。
现在,将其与
的成本进行比较如果每个数字的13个指令是执行时间的重要组成部分,那么您正在执行非常高性能的任务,并且应该以正确的格式输入您的输入!您也可能不会使用托管语言,因为您需要更多地控制数据缓冲区和什么不是,并且没有额外的数组边界检查。
如果该数据数据来自网络,我预计管理套接字的成本会比单纯的字节顺序翻转要大得多,如果它来自磁盘,则考虑在执行此程序之前预先翻转。 / p>
答案 2 :(得分:1)
我想考虑两个因素 类型为ulong类型
那么,这也会交换两个uint值,这可能是不可取的......
您可以在不安全模式下尝试一些C#代码,这可能实际上表现得足够好。像:
public static unsafe void SwapInts(uint[] data) {
int cnt = data.Length;
fixed (uint* d = data) {
byte* p = (byte*)d;
while (cnt-- > 0) {
byte a = *p;
p++;
byte b = *p;
*p = *(p + 1);
p++;
*p = b;
p++;
*(p - 3) = *p;
*p = a;
p++;
}
}
}
在我的计算机上,吞吐量大约为每秒2 GB。