Преобразование кода руки для использования встроенных функций NEON

Я пытался изменить приведенный ниже код для работы с NEON Intrinsics, тем самым создав ускорение. К сожалению, ничего не работает правильно. Кто-нибудь знает, что происходит не так? Я обновил двойники до одиночных элементов с плавающей запятой.

typedef         float       REAL;
typedef         REAL        VEC3[3];    

typedef struct  driehoek
{
    VEC3        norm;                   /* Face normal. */
    REAL        d;                      /* Plane equation D. */
    VEC3        *vptr;                  /* Global vertex list pointer. */
    VEC3        *nptr;                  /* Global normal list pointer. */
    INT         vindex[3];              /* Index of vertices. */
    INT         indx;                   /* Normal component max flag. */
    BOOL        norminterp;             /* Do normal interpolation? */
    BOOL        vorder;                 /* Vertex order orientation. */
}driehoek;

typedef struct element
{
    INT         index;
    struct object   *parent;            /* Ptr back to parent object.    */
    CHAR        *data;                  /* Pointer to data info.         */
    BBOX        bv;                     /* Element bounding volume.      */
}ELEMENT;

INT TriangleIntersection(RAY *pr, ELEMENT *pe, IRECORD *hit)
{
    FLOAT      Rd_dot_Pn;       /* Polygon normal dot ray direction. */
    FLOAT      Ro_dot_Pn;       /* Polygon normal dot ray origin.    */
    FLOAT      q1, q2;
    FLOAT      tval;            /* Intersection t distance value.    */
    VEC3       *v1, *v2, *v3;       /* Vertex list pointers.         */
    VEC3       e1, e2, e3;      /* Edge vectors.             */
    driehoek   *pt;         /* Ptr to triangle data.         */


    pt = (driehoek *)pe->data;

    Rd_dot_Pn = VecDot(pt->norm, pr->D);

    if (ABS(Rd_dot_Pn) < RAYEPS)        /* Ray is parallel.      */
        return (0);

        hit->b3 = e1[0] * (q2 - (*v1)[1]) - e1[1] * (q1 - (*v1)[0]);
        if (!INSIDE(hit->b3, pt->norm[2]))
            return (0);
        break;
    }

    return (1);
 }

person Alex van Rijs    schedule 14.05.2013    source источник
comment
Как вы используете NEON Intrinsics? Вы пока не используете ничего из этого в своем коде.   -  person auselen    schedule 15.05.2013


Ответы (1)


Массив float vec[3] не является подсказкой компилятору о том, что можно использовать встроенный NEON. Проблема в том, что в float vec[3] каждый элемент адресуется индивидуально. Компилятор должен хранить каждое значение в регистре с плавающей запятой. См. внутренний компонент gcc NEON документация.

Хотя трехмерность очень распространена в этой Вселенной, нашим друзьям-компьютерам нравятся двоичные числа. Итак, у вас есть два типа данных, которые можно использовать для встроенных функций NEON; float32x4_t и float32x2_t. Вам нужно использовать встроенные функции, такие как vfmaq_f32, vsubq_f32 и т. д. Эти встроенные функции различны для каждого компилятора; Я думаю, вы используете gcc. Вы должны использовать только внутренние типы данных, так как объединение float32x2_t с одним float может привести к перемещению между типами регистров, что является дорогостоящим. Если ваш алгоритм может обрабатывать каждое измерение отдельно, вы можете комбинировать типы. Однако я не думаю, что у вас возникнет регистрация давления, и ускорение SIMD должно быть полезным. Для начала я бы оставил все в float32x4_t. Возможно, вы сможете использовать дополнительное измерение для 3D-проекции, когда дело доходит до этапа рендеринга.

Вот источник cmath библиотека под названием math-neon в LGPL. Вместо использования внутренностей с gcc используется встроенный ассемблер.Неоновые встроенные свойства и сборка

См. также: armcc встроенные функции NEON, если вы используете компилятор ARM.

person artless noise    schedule 14.05.2013
comment
OpenCV Neon Intrinscis имеет реализацию, но ее сложнее понять, поскольку она предоставляет API для AVX/SSE и других наборов инструкций SIMD. - person artless noise; 03.03.2021