我需要在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周期非常重要.
如今,执行指令的数量和执行它们所需的CPU周期数之间没有直接的联系.您似乎也假设C#中的语句对应于单个程序集/ cpu指令,这也是错误的.
您的代码似乎正确地执行了算法描述所说的内容(请注意long已签名,对未签名行为使用ulong).
如果要使用可在一条指令中执行add-shift-assignment的专用cpu扩展(如mmx,sse等),则需要使用汇编代码.但我不确定是否存在这样的具体指令.这可能取决于您拥有的CPU类型.
您不能将汇编代码与c#一起直接使用,但您可以将汇编与c一起使用(作为链接的目标文件使用,使其成为内联汇编).编译后的c代码可以从c#/ .net与interop一起使用.
但对你而言,第一个也是最重要的问题应该是:你想要完成什么?
我怀疑性能对您的应用程序至关重要,即使您应该诚实地问自己c#是否是您目标的最佳语言.
另一个想法是预先计算所有字节值的查找表。
var lu = new long[256];
// init
var n = 7;
var v = lu[n];
Run Code Online (Sandbox Code Playgroud)
更新
一些基准测试结果(以每 100000000 次迭代的毫秒为单位):
展开的版本是:
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。
| 归档时间: |
|
| 查看次数: |
327 次 |
| 最近记录: |