How does redundant if-else help optimize?

I read the source code of the library Python numpyand found the following snippets. It seems that it performs elementary operations on vectors ( numpy.ndarray). For example, numpy.multiply([1,2,3],[4,5,6])get the result[4,10,18]

#define BASE_UNARY_LOOP(tin, tout, op) \
    UNARY_LOOP { \
        const tin in = *(tin *)ip1; \
        tout * out = (tout *)op1; \
        op; \
    }
#define UNARY_LOOP_FAST(tin, tout, op) \
    do { \
    /* condition allows compiler to optimize the generic macro */ \
    if (IS_UNARY_CONT(tin, tout)) { \
        if (args[0] == args[1]) { \
            BASE_UNARY_LOOP(tin, tout, op) \
        } \
        else { \
            BASE_UNARY_LOOP(tin, tout, op) \
        } \
    } \
    else { \
        BASE_UNARY_LOOP(tin, tout, op) \
    } \
    } \
    while (0)

It looks very strange to me, especially the comment inside UNARY_LOOP_FAST. What happens here using if A then X else Xlogic to optimize?

+4
source share
2 answers

This clip is from

https://github.com/numpy/numpy/blob/master/numpy/core/src/umath/loops.c.src

This particular clip defines loop macros for one argument ufunc, something like np.abs.

/* * * op , tin in * tout * out * NPY_GCC_OPT_3, autovectorization *, , */

ufunc np.sin(a, out=b). -, , tout tin, np.sin(a, out=a).

, ufunc np.add(a, b, out=c), c=a+b, a += b, b+=a.


, , args[0] == args[1]

In [195]: a=np.ones((100,100))
In [197]: %%timeit b=np.ones((100,100))
     ...: np.sin(a, out=b)
1000 loops, best of 3: 343 µs per loop

In [198]: %%timeit b=np.ones((100,100))
     ...: np.sin(b, out=b)
1000 loops, best of 3: 279 µs per loop
0

, numpy, , , :

#define LOOP(op) for (int i = 0; i < n; i++) op

void f(int *a, int *b, int n, int c) {
  if (c == 1) {
    LOOP(a[i] += b[i] * c);
  }
  else {
    LOOP(a[i] += b[i] * c);
  }
}

. LOOP(a[i] += b[i]) , if , op , .

, , , .

+2

Source: https://habr.com/ru/post/1669239/


All Articles