https://blog.csdn.net/xindoo/article/details/101762198
微机原理
https://www.docin.com/p-2216550141.html
https://blog.csdn.net/jasonchen_gbd/article/details/44948523
__builtin_ffs(x): 返回x中最后一个为1的位是从后向前的第几位 __builtin_popcount(x): x中1的个数 __builtin_ctz(x): x末尾0的个。x=0时结果无意义 __builtin_clz(x): x前导0的个数。x=0时结果未定义 __builtin_prefetch(const void *addr,...):对数据手工预取的方法 __builtin_types_compatible_p(type1, type2): 判断type1和type2是否是相同的数据类型 __builtin_expect(long exp, long c): 用来引导gcc进行条件分支预测 __builtin_constant_p(exp): 判断exp是否在编译时就可以确定其为常量 __builtin_parity(x): x中1的奇偶性 __builtin_return_oddress(n): 当前函数的第n级调用者的地址#define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0)
!! 是逻辑归一化处理 x 的属性值依然还是没改变。
例1
bool isPalindrome(int x) { if (__builtin_expect(!!(x < 0), 0) return false; int y = 0, z = x; while (x) { y = y*10 + x % 10; x /= 10; } return z == y; }例2
参加上面引用文章,这里结合了 位运算符
我们有如下两段代码,代码看起来都是差不多的,实际上逻辑也是一样的,都是统计数组中小于THRESHOLD数的个数,唯一的区别是一个是在无序数组中统计,另一个是在有序数组中统计。如果两个数组数据源是一致的(数组大小、数据都是一致的),只是一个无序一个有序,你觉得两个函数的性能差距会有多大?
@BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MICROSECONDS) @State(Scope.Thread) @Fork(3) @Warmup(iterations = 1) @Measurement(iterations = 3) public class BranchPredictionTest { private static Random random = new Random(); private static int MAX_LENGTH = 10_000_000; private static int[] arr; private static int[] arrSotred; private static int THRESHLOD = MAX_LENGTH >> 1; @Setup public static void init() { arr = new int[MAX_LENGTH]; for (int i = 0; i < MAX_LENGTH; i++) { arr[i] = random.nextInt(MAX_LENGTH); } arrSotred = Arrays.copyOf(arr, arr.length); Arrays.sort(arrSotred); } @Benchmark public static void countUnsortedArr() { int cnt = 0; for (int i = 0; i < MAX_LENGTH; i++) { if (arr[i] < THRESHLOD) { cnt++; } } } @Benchmark public static void countSortedArr() { int cnt = 0; for (int i = 0; i < MAX_LENGTH; i++) { if (arrSotred[i] < THRESHLOD) { cnt++; } } } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(BranchPredictionTest.class.getSimpleName()) .forks(1) .build(); new Runner(opt).run(); } }