标签: micro-optimization

智能JVM和JIT微优化

随着时间的推移,Sun的JVM和JIT变得非常聪明.以前不再需要将常识作为必要的微优化的东西,因为它会得到照顾.

例如,过去应该将所有可能的类标记为final,因此JVM会尽可能多地内联代码.但是现在,JIT根据在运行时加载的类知道你的类是否是最终的,如果加载一个类使原始类不可能,它会取消内联方法并取消标记为最后.

JVM或JIT还为您做了哪些其他智能微优化?

编辑:我把它做成了社区维基; 我想随着时间的推移收集它们.

java jit jvm micro-optimization

6
推荐指数
1
解决办法
894
查看次数

在scala中减去两个数组的最快方法是什么?

我有两个数组(我已经退出矩阵(Array [Array [Int]]),我需要从另一个中减去一个.

目前我正在使用这种方法,当我对它进行分析时,它就是瓶颈.

def subRows(a: Array[Int], b: Array[Int], sizeHint: Int): Array[Int] = {
   val l: Array[Int] = new Array(sizeHint)
   var i = 0
   while (i < sizeHint) {
     l(i) = a(i) - b(i)
     i += 1
   }
   l
 }
Run Code Online (Sandbox Code Playgroud)

我需要做数十亿次,所以速度的提高是有利的.

我已经尝试使用a List而不是a Array来收集差异并且速度更快但是当我将其转换回来时我失去了所有好处Array.

我确实修改了下游代码,List看看是否会有所帮助,但我需要不按顺序访问列表中的内容,所以再次失去任何收益.

似乎任何一种类型的转换都是昂贵的,我想知道是否有某种方法可以使用可能更快的地图等.

有没有更好的办法?


编辑

不知道我第一次做了什么!?

所以我用来测试它的代码是这样的:

def subRowsArray(a: Array[Int], b: Array[Int], sizeHint: Int): Array[Int] = {
  val l: Array[Int] = new Array(sizeHint)
  var i = 0
  while (i < sizeHint) …
Run Code Online (Sandbox Code Playgroud)

scala micro-optimization scala-2.9

6
推荐指数
1
解决办法
2936
查看次数

如何加速棘手的随机数生成

我有一些代码执行许多日志tancos双打操作.我需要这个尽可能快.目前我使用的代码如

#include <stdio.h>
#include <stdlib.h>
#include "mtwist.h"
#include <math.h>


int main(void) {
   int i;
   double x;
   mt_seed();
   double u1;
   double u2;
   double w1;
   double w2;
   x = 0;
   for(i = 0; i < 100000000; ++i) {
     u1 = mt_drand();
     u2 = mt_drand();
     w1 = M_PI*(u1-1/2.0);
     w2 = -log(u2);
     x += tan(w1)*(M_PI_2-w1)+log(w2*cos(w1)/(M_PI_2-w1));
   }
   printf("%f\n",x); 

   return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用gcc.

有两种明显的方法可以加快速度.首先是选择更快的RNG.第二是加快先验功能.
要做到这一点,我想知道

  1. 如何在x86上的程序集中实现tan和cos?我的CPU是AMD FX-8350,如果它有所作为.(答案fcoscosfptantan.)
  2. 如何使用查找表来加速计算?我只需要32位的精度.例如,你可以使用一个大小为2 ^ 16的表来加速tan和cos操作吗?

英特尔优化手册

如果不需要使用80位的扩展精度来评估超越函数,则应用程序应考虑使用基于软件的替代方法,例如使用插值技术的基于查找表的算法.通过选择所需的数值精度和查找表的大小,并利用SSE和SSE2指令的并行性,可以通过这些技术提高超越性能. …

c math performance assembly micro-optimization

6
推荐指数
4
解决办法
795
查看次数

java micro-optimization:将一组布尔实例变量与基于int的位向量相结合

我们有一个包含许多实例的类,并遇到内存问题.因此,我们尝试减少这个类的内存需求.一个想法是以下.

该类有许多布尔实例变量,每个变量在初始实现中占用一个单词.可以想到将它们组合到存储在int中的迷你位向量,使得它们的组合存储器要求将是一个字.

但我怀疑Java VM正在进行这种优化,因此手动执行它不会获得任何额外的节省.对?

java boolean micro-optimization bitvector

6
推荐指数
2
解决办法
184
查看次数

为什么.Net Native以相反的顺序编译循环?

我正在研究.Net Native编译器执行的优化技术.我创建了一个示例循环:

        for (int i = 0; i < 100; i++)
        {
            Function();
        }
Run Code Online (Sandbox Code Playgroud)

我用Native编译了它.然后我.dll用IDA里面的机器代码反汇编了结果文件.结果,我有:

在此输入图像描述

(我删除了一些不必要的行,所以不要担心地址行不一致)

我明白这add esi, 0FFFFFFFFh意味着subtract one from esi and alter Zero Flag if needed,所以如果还没有达到零,我们可以跳到开头.

我不明白的是为什么编译器重新循环?

我得出结论

LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
Run Code Online (Sandbox Code Playgroud)

比例如更快

LOOP:
inc esi
cmp esi, 064h
jl LOOP
Run Code Online (Sandbox Code Playgroud)

但是真的是因为这个并且速度差异真的很重要吗?

c# x86 assembly micro-optimization .net-native

6
推荐指数
1
解决办法
160
查看次数

确定寄存器的值是否等于零的最简单方法是什么?

我正在使用与Irvine库的x86程序集.

检查寄存器值是否等于零的最简单方法是什么?

我使用cmp指令,但我正在寻找替代方法.这是我使用cmp指令的代码,寄存器是ebx

    cmp ebx,0
    je equ1
    mov ebx,0
    jmp cont
equ1:
    mov ebx,1
    jmp cont
cont:
    exit
Run Code Online (Sandbox Code Playgroud)

这个"booleanizes"一个值,int ebx = !!ebx在C中产生0或1 .

x86 assembly micro-optimization

6
推荐指数
1
解决办法
4378
查看次数

为什么strtolower比strtoupper略慢?

我出于好奇做了一个实验.我想看看是否有在所有之间的差异微strtolower()strtoupper().我预计strtolower()大多数小写字符串会更快,反之亦然.我发现这种strtolower()情况在所有情况下都比较慢(尽管在你完成数百万次之前完全无关紧要.)这是我的考验.

$string = 'hello world';
$start_time = microtime();
for ($i = 0; $i < 10000000; $i++) {
    strtolower($string);
}
$timed = microtime() - $start_time;
echo 'strtolower ' . $string . ' - ' . $timed . '<br>';
Run Code Online (Sandbox Code Playgroud)

重复strtolower()strtoupper()使用hello world,HELLO WORLD以及Hello World.这是完整的要点.我已经多次运行代码并继续获得大致相同的结果.这是下面的一次测试.

strtolower hello world - 0.043829
strtoupper hello world - 0.04062
strtolower HELLO WORLD - 0.042691
strtoupper HELLO WORLD - …
Run Code Online (Sandbox Code Playgroud)

php c performance micro-optimization

6
推荐指数
1
解决办法
867
查看次数

_mm256_lddqu_si256和_mm256_loadu_si256之间有什么区别

_mm256_lddqu_si256基于我在网上找到的一个例子,我一直在使用.后来我发现了_mm256_loadu_si256.英特尔内在函数指南仅指出lddqu版本在跨越缓存行边界时可能表现更好.可能有什么好处loadu?一般来说,这些功能有何不同?

x86 simd intrinsics avx micro-optimization

6
推荐指数
1
解决办法
903
查看次数

函数所需的堆栈空间是否会影响C/C++中的内联决策?

函数需要大量的堆栈空间是否会阻止它内联?例如,如果我在堆栈上有一个10k自动缓冲区,是否会使该函数不太可能被内联?

int inlineme(int args) {
  char svar[10000];

  return stringyfunc(args, svar);
}
Run Code Online (Sandbox Code Playgroud)

我更关心gcc,但icc和llvm也很高兴知道.

我知道这不太理想,但我很好奇.缓存上的代码很可能也很糟糕.

c c++ gcc inline micro-optimization

6
推荐指数
1
解决办法
243
查看次数

在__uint128_t上最有效的popcount?

我需要以最有效(最快)的方式来弹出大小为128位的无符号变量。

  • 操作系统:Linux / Debian 9
  • 编译器:GCC 8
  • 处理器:Intel i7-5775C

尽管解决方案便携,甚至更好。

首先,GCC中有两种类型,分别是__uint128_tunsigned __int128。我猜他们最终还是一样,看不出有什么理由写丑陋的unsigned __int128东西,因此尽管它应该是新类型,但我更喜欢第一个,它与标准更加相似uint64_t。另外,英特尔拥有__uint128_t使用它的另一个原因(可移植性)。

我写了以下代码:

#include <nmmintrin.h>
#include <stdint.h>

static inline   uint_fast8_t    popcnt_u128 (__uint128_t n)
{
    const uint64_t      n_hi    = n >> 64;
    const uint64_t      n_lo    = n;
    const uint_fast8_t  cnt_hi  = _mm_popcnt_u64(n_hi);
    const uint_fast8_t  cnt_lo  = _mm_popcnt_u64(n_lo);
    const uint_fast8_t  cnt     = cnt_hi + cnt_lo;

    return  cnt;
}
Run Code Online (Sandbox Code Playgroud)

这是绝对最快的选择吗?

编辑:

我想到了另一个选择,它可能会(或不会)更快:

#include <nmmintrin.h>
#include <stdint.h>

union   Uint128 {
    __uint128_t …
Run Code Online (Sandbox Code Playgroud)

c gcc x86-64 intel micro-optimization

6
推荐指数
1
解决办法
319
查看次数

标签 统计

micro-optimization ×10

c ×4

assembly ×3

x86 ×3

gcc ×2

java ×2

performance ×2

.net-native ×1

avx ×1

bitvector ×1

boolean ×1

c# ×1

c++ ×1

inline ×1

intel ×1

intrinsics ×1

jit ×1

jvm ×1

math ×1

php ×1

scala ×1

scala-2.9 ×1

simd ×1

x86-64 ×1