Либо равны, либо не перекрываются - PullRequest
1 голос
/ 03 ноября 2019

Скажем, функция, которая добавляет два вектора

void add256(int* r, int* p, int* q) {
    for (int i=0; i<256; ++i) {
        r[i] = p[i] + q[i];
    }
}

Теперь, если я знаю, r либо p, либо не в том же массиве с p и одинаковым с q,Может ли restrict помочь оптимизировать код с помощью инструкции параллельного добавления?


Я задал этот вопрос, потому что в GCC

typedef struct { int x[256]; } int256;
void add256t(int256* r, int256* p, int256* q) {
    for (int i=0; i<256; ++i) {
        r->x[i] = p->x[i] + q->x[i];
    }
}

можно оптимизировать с точно предполагаемыми условиями и длямой предполагаемый asm, но разделение в другой ситуации делает код беспорядком и разделением asm, делая то же самое

1 Ответ

0 голосов
/ 04 ноября 2019

Когда вы используете restrict, вы даете обещание компилятору. Нарушение этого обещания ведет к неопределенному поведению.

То, как я интерпретирую ваш вопрос, состоит в том, что указатели либо совпадают, либо не перекрываются вообще. В этом случае вы можете оптимизировать следующим образом:

void add256_rEQp(int restrict *r, int restrict *q) {
    for (int i=0; i<256; ++i) {
        r[i] += q[i];
    }
}

void add256(int* r, int* p, int* q) {
    if(r == p && r != q)
        add_256rEQp(r, q);
    else if( ...
    else {
        for (int i=0; i<256; ++i) {
            r[i] = p[i] + q[i];
        }
    }
}

Но, конечно, вы должны запустить тесты, чтобы увидеть, улучшает ли это производительность. В конце концов, это немного увеличивает накладные расходы.

...