是否有可以从c#访问的移位和复制cpu指令?

本文关键字:复制 cpu 指令 访问 是否 | 更新日期: 2023-09-27 18:09:09

我需要在64位cpu上取8位数字并将其右移8次。每次我移动这个数字时,我都需要在它后面移动相同的8位数字,这样我就得到了相同的8位数字,重复了8次。这最终会变成shift,加8,shift加8…等等,最终是40多个周期(如果我错了请纠正我)。

是否有一种方法可以在1个周期内执行此操作(移位和复制),以便我最终获得相同的值?

long _value = 0;
byte _number = 7;
for (int i = 0; i < 8; i++) {
    _value = (_value << 8) + _number;
}

编辑:我正试图比较一个字符流来检测关键字。我不能用绳子。包含,因为字符串值可能跨越缓冲区的边界。此外,应用程序必须在嵌入式ARM cpu以及桌面和服务器cpu上运行。内存使用和cpu周期非常重要。

是否有可以从c#访问的移位和复制cpu指令?

目前,执行指令的数量与执行所需的cpu周期数之间并没有直接的联系。您似乎还假设c#中的语句对应于单个汇编/cpu指令,这也是错误的。

你的代码似乎正确地做了你的算法描述(注意,long是有符号的,使用ulong对于无符号行为)。

如果您想使用专门的cpu扩展(如mmx,sse等),可以在一条指令中执行add-shift-assignment,则需要使用汇编代码。但我不确定是否存在这样的具体指示。这可能取决于您的CPU类型。

不能直接将汇编代码与c#一起使用,但可以将汇编代码与c一起使用(无论是作为链接对象文件还是使用内联汇编)。编译后的c代码可以在c#/.net中使用互操作

但是第一个重要的问题应该是:你想要完成什么?

我怀疑性能对你的应用程序是否如此重要,即使如此,你也应该诚实地问自己c#是否是最适合你目标的语言。

另一个想法是在查找表中为字节的所有值预先计算所有值。

var lu = new long[256];
// init
var n = 7;
var v = lu[n];

一些基准测试结果(以ms/100000000次迭代为单位):

  • 循环:272
  • 展开:207
  • 不安全:351
  • 查找:250
  • HenkH: 216

展开的版本是:

long _value = 0;
byte _number = 7;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;
_value = (_value + _number) << 8;

不安全的版本是:

long _value = 0;
byte _number = 7;
byte* p = (byte*)&_value;
*p++ = _number;
*p++ = _number;
*p++ = _number;
*p++ = _number;
*p++ = _number;
*p++ = _number;
*p++ = _number;
*p++ = _number;

遗憾的没有执行:(

查找只是读取一个数组。

如果你想让它更快,你至少可以展开你的循环:

ulong _value = 0;
byte _number = 7;
_value = _number;
_value = (_value <<  8) + _value;
_value = (_value << 16) + _value;
_value = (_value << 32) + _value;

这也会有更少的分支。