Tag: 优化

如何加快浮点到整数转换?

我们在项目中进行了大量的浮点数到整数转换。 基本上,这样的事情 for(int i = 0; i < HUGE_NUMBER; i++) int_array[i] = float_array[i]; 执行转换的默认C函数非常耗时。 是否有任何工作(可能是手动调整function)可以加快一点点的过程? 我们不太关心精度。

哪个更快/更首选:memset或for循环将双精度数组归零?

double d[10]; int length = 10; memset(d, length * sizeof(double), 0); //or for (int i = length; i–;) d[i] = 0.0;

格雷码递增函数

在不使用任何外部计数器或其他状态的情况下,我正在寻找一个有效的函数,该函数采用n位值(32位或左右)并返回格雷码中的后续值。 那是: int fn(int x) { int y = gray_to_binary(x); y = y + 1; return binary_to_gray(y); } 但是虽然binary_to_gray()函数是微不足道的( x ^ (x >> 1) ),但相应的gray_to_binary()根本不是那么简单( log(n)迭代的循环)。 也许有一个更有效的操作序列? 对于标准reflection格雷码,或者为了解决此问题而选择的另一格雷码。 旁白:我看到这个问题有两种可能的解决方案类型 – 一种是选择一种更容易转换为二进制的代码并使用上面给出的forms(或者为了反映代码演示更有效的二进制转换),以及另一种方法是将转换推迟到二进制并生成一种方法,该方法在不使用二进制增量的情况下遍历格雷码。 在后一种情况下,将结果代码转换为二进制代码可能会变得特别困难。 从实际角度来看,这可能是一个不利因素,但它仍然是一件有趣的事情。 更新:因为有人指出灰色解码只是log(n)操作(使用两种不同技术中的任何一种),我花了一些时间试图弄清楚这是否是对事物可以简化的严格限制。 在确定要执行的下一个操作时必须考虑所有位,否则“考虑”位将无法改变,并且函数将在两个值之间振荡。 必须以某种方式将输入压缩为可管理的比例,以确定要执行的下一个操作。 为了使其成为log(nk)操作,可以使用2k -entry LUT来缩短最后的k操作(注释表明k=32 )。 另一种可以经常减少事物的技术是乘法和位掩码的组合。 例如,计算奇偶校验以实现基于奇偶校验的算法。 从乘法和位掩码的方法来看,似乎可能有空间来发明格雷码,这进一步简化了操作集……但我不认为任何这样的代码是已知的。

快速检查字符数组是否为零的方法

我在内存中有一个字节数组。 查看数组中所有字节是否为零的最快方法是什么?

确定字节中的哪个位被设置

我有一个用于bitflags的byte 。 我知道在任何给定时间都设置了byte中的一个且只有一个位。 例如: unsigned char b = 0x20; //(00100000) 6th most bit set unsigned char b = 0x20; //(00100000) 6th most bit set 我目前使用以下循环来确定设置了哪个位: int getSetBitLocation(unsigned char b) { int i=0; while( !((b >> i++) & 0x01) ) { ; } return i; } 如何最有效地确定设定位的位置? 我可以不经迭代地完成这项工作吗?

使用SSE最快地实现指数函数

我正在寻找在SSE元素上运行的指数函数的近似值。 即 – __m128 exp( __m128 x ) 。 我有一个快速但实际上准确度非常低的实现: static inline __m128 FastExpSse(__m128 x) { __m128 a = _mm_set1_ps(12102203.2f); // (1 << 23) / ln(2) __m128i b = _mm_set1_epi32(127 * (1 << 23) – 486411); __m128 m87 = _mm_set1_ps(-87); // fast exponential function, x should be in [-87, 87] __m128 mask = _mm_cmpge_ps(x, m87); […]

memset()是否接受大于char的整数?

是否有一个memset()版本设置一个大于1字节(char)的值? 例如,假设我们有一个memset32()函数,所以使用它我们可以执行以下操作: int32_t array[10]; memset32(array, 0xDEADBEEF, sizeof(array)); 这将在数​​组的所有元素中设置值0xDEADBEEF。 目前在我看来这只能通过循环来完成。 具体来说,我对64位版本的memset()感兴趣。 知道这样的事吗?

如何在C中连接两个整数

Stack Overflow已经用许多其他语言回答了这个问题,但不是C.所以我想我会问,因为我有同样的问题。 如何在C中连接两个整数? 例: x = 11; y = 11; 我想z如下: z = 1111; 其他示例尝试使用字符串执行此操作。 没有字符串的方法是什么? 我正在寻找一种在C中执行此操作的有效方法,因为在我的特定用法中,这将成为代码的时间关键部分。 提前致谢!

如何确定内存是否对齐?

我是使用SSE / SSE2指令优化代码的新手,直到现在我还没有走得太远。 据我所知,常见的SSE优化函数如下所示: void sse_func(const float* const ptr, int len){ if( ptr is aligned ) { for( … ){ // unroll loop by 4 or 2 elements } for( ….){ // handle the rest // (non-optimized code) } } else { for( ….){ // regular C code to handle non-aligned memory } } } […]

高效的4×4矩阵乘法(C vs汇编)

我正在寻找一种更快,更棘手的方法来将C中的两个4×4矩阵相乘。我目前的研究主要集中在具有SIMD扩展的x86-64汇编上。 到目前为止,我已经创建了一个函数,比一个简单的C实现快了大约6倍,这超出了我对性能改进的期望。 不幸的是,只有在没有使用优化标志进行编译时(GCC 4.7),这种情况才会成立。 随着-O2 ,C变得更快,我的努力变得毫无意义。 我知道现代编译器利用复杂的优化技术来实现几乎完美的代码,通常比巧妙的手工assembly更快。 但在少数性能关键的情况下,人类可能会尝试使用编译器争取时钟周期。 特别是,当一些支持现代ISA的数学可以被探索时(就像我的情况一样)。 我的函数如下(AT&T语法,GNU汇编程序): .text .globl matrixMultiplyASM .type matrixMultiplyASM, @function matrixMultiplyASM: movaps (%rdi), %xmm0 # fetch the first matrix (use four registers) movaps 16(%rdi), %xmm1 movaps 32(%rdi), %xmm2 movaps 48(%rdi), %xmm3 xorq %rcx, %rcx # reset (forward) loop iterator .ROW: movss (%rsi), %xmm4 # Compute four values (one row) […]