我是指令优化的新手.
我对一个简单的函数dotp进行了简单的分析,该函数用于获取两个浮点数组的点积.
C代码如下:
float dotp(
const float x[],
const float y[],
const short n
)
{
short i;
float suma;
suma = 0.0f;
for(i=0; i<n; i++)
{
suma += x[i] * y[i];
}
return suma;
}
Run Code Online (Sandbox Code Playgroud)
我用昂纳雾在网络上提供的测试框架testp.
在这种情况下使用的数组是对齐的:
int n = 2048;
float* z2 = (float*)_mm_malloc(sizeof(float)*n, 64);
char *mem = (char*)_mm_malloc(1<<18,4096);
char *a = mem;
char *b = a+n*sizeof(float);
char *c = b+n*sizeof(float);
float *x = (float*)a;
float *y = (float*)b;
float *z = (float*)c;
Run Code Online (Sandbox Code Playgroud)
然后我调用函数dotp,n = 2048,repeat …
世界上为什么_mm_crc32_u64(...)这样定义?
unsigned int64 _mm_crc32_u64( unsigned __int64 crc, unsigned __int64 v );
Run Code Online (Sandbox Code Playgroud)
"crc32"指令总是累加32位CRC,而不是 64位CRC(毕竟,CRC32不是CRC64).如果机器指令CRC32 恰好具有64位目标操作数,则忽略高32位,并在完成时填充0,因此没有使用EVER具有64位目标.我理解为什么英特尔允许在指令上使用64位目标操作数(为了均匀性),但是如果我想快速处理数据,我想要一个尽可能大的源操作数(即如果我有那么多数据,则为64位,尾部较小)并且始终是32位目标操作数.但内在函数不允许使用64位源和32位目标.注意其他内在函数:
unsigned int _mm_crc32_u8 ( unsigned int crc, unsigned char v );
Run Code Online (Sandbox Code Playgroud)
"crc"的类型不是8位类型,也不是返回类型,它们是32位.为什么没有
unsigned int _mm_crc32_u64 ( unsigned int crc, unsigned __int64 v );
Run Code Online (Sandbox Code Playgroud)
?英特尔指令支持这一点,这是最有意义的内在因素.
有没有人有可移植代码(Visual Studio和GCC)来实现后者的内在?谢谢. 我的猜测是这样的:
#define CRC32(D32,S) __asm__("crc32 %0, %1" : "+xrm" (D32) : ">xrm" (S))
Run Code Online (Sandbox Code Playgroud)
对于GCC,和
#define CRC32(D32,S) __asm { crc32 D32, S }
Run Code Online (Sandbox Code Playgroud)
对于VisualStudio.不幸的是,我对约束如何工作几乎一无所知,并且对汇编级编程的语法和语义缺乏经验.
小编辑:记下我定义的宏:
#define GET_INT64(P) *(reinterpret_cast<const uint64* &>(P))++
#define GET_INT32(P) *(reinterpret_cast<const uint32* …Run Code Online (Sandbox Code Playgroud) 我需要使用 CRC32C(CRC32 计算的 Castagnoli 变体)来验证数据。我在任何地方都找不到可以计算此值以验证相关值的独立命令行实用程序。CRC32?MD5?沙?查看。CRC32C?你输了。
我需要一个程序。必须是自包含的(没有需要安装的非标准 PERL 或 Python 模块......标准模块是可以的)。可能没有 Java,因为我不能保证安装 Java。Ruby 就出来了。
聪明的“gzip”或“tar”技巧很好。需要在 OS-X、Linux 和 Android 上运行。
我确实可以写一个(代码在 RFC 中),但是来吧......这有点像
“嗯,我的车用的是合成油……该换油了,我去当地的炼油厂打几夸脱吧”
或者
“比尔叔叔想要一个 PB&J 三明治,但他对麸质过敏……让我去拿些米粉做无麸质面包”。
我找到了一些库来计算 CRC32C,但没有程序。叽。
https://developers.google.com/storage/docs/composite-objects?hl=ja
如果我有子串 S 0 , S 1 , ... S n与计算的 CRCs C 0 , C 1 , ... C n,我是否能够确定连接输入 S 0 S 1的 CRC C 0...n ...S n比线性处理整个字符串的效率要高得多?
显然, C 0...n = CRC(S 1...n,用 C 0初始化),但我想知道 C 0...n = f(C 0 ,C 1 ,... C n ) 用于某些具有 O(n) 复杂度的 f() 而不是 O(|S 0 S 1 ...S n |)。
我有以下代码(手动版本来自阿德勒的答案)
#include <iostream>
#include <nmmintrin.h>
#define POLY2 0x82f63b78
uint32_t crc32c2(uint32_t crc, const unsigned char *buf, size_t len)
{
int k;
crc = ~crc;
while (len--) {
crc ^= *buf++;
for (k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ POLY2 : crc >> 1;
}
return ~crc;
}
int main(int argc, char **argv)
{
const unsigned int val = 5;
std::cout << std::hex << crc32c2(0,(const unsigned char*)&val,4) << std::endl;
std::cout …Run Code Online (Sandbox Code Playgroud) 在我的项目中,CRC32计算了很多次。到目前为止,我一直使用软件CRC32计算。但是我注意到SSE4.2中有CPU支持,并且linux还使用CPU指令提供了硬件CRC32计算功能。我使用Intel Xeon E5-2650 CPU,因此尝试使用linux函数计算CRC32。但是结果与我使用的软件CRC32功能不同。我在两者中都使用了init值127。我使用的软件CRC32功能如下
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, …Run Code Online (Sandbox Code Playgroud)