是否有可以从c#访问的shift和copy cpu指令?

6 c# assembly

我需要在64位cpu上取一个8位数字并将其向右移动8次.每次我移动数字我需要在它后面移动相同的8位数,这样我最终会重复8次相同的8位数.这最终会转移,添加8,转移添加8 ...等等,最终是40多个周期(如果我错了,请纠正我).

有没有办法在1个循环中执行此操作(移位和复制),以便最终得到相同的值?

long _value = 0;
byte _number = 7;
for (int i = 0; i < 8; i++) {
    _value = (_value << 8) + _number;
}
Run Code Online (Sandbox Code Playgroud)

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

cod*_*nix 6

如今,执行指令的数量和执行它们所需的CPU周期数之间没有直接的联系.您似乎也假设C#中的语句对应于单个程序集/ cpu指令,这也是错误的.

您的代码似乎正确地执行了算法描述所说的内容(请注意long已签名,对未签名行为使用ulong).

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

您不能将汇编代码与c#一起直接使用,但您可以将汇编与c一起使用(作为链接的目标文件使用,使其成为内联汇编).编译后的c代码可以从c#/ .net与interop一起使用.

但对你而言,第一个也是最重要的问题应该是:你想要完成什么?

我怀疑性能对您的应用程序至关重要,即使您应该诚实地问自己c#是否是您目标的最佳语言.


lep*_*pie 4

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

var lu = new long[256];
// init
var n = 7;
var v = lu[n];
Run Code Online (Sandbox Code Playgroud)

更新

一些基准测试结果(以每 100000000 次迭代的毫秒为单位):

  • 循环:272
  • 展开:207
  • 不安全:351
  • 查找次数:250
  • 亨克H: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;
Run Code Online (Sandbox Code Playgroud)

不安全的版本是:

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;
Run Code Online (Sandbox Code Playgroud)

遗憾的是没有表演:(

查找只是对数组的读取。

全部编译为 x64/release。