Использование ограничений с массивами?

Есть ли способ сказать компилятору C99, что единственный способ, которым я получаю доступ к данному массиву, - это использовать myarray [index]? Скажите примерно так:

int heavy_calcualtions(float* restrict range1, float* restrict range2)
{
    float __I promise I won't alias this__ tmpvalues[1000] = {0};

    ....
    heavy calculations using range1, range2 and tmpvalues;
    ....
}

Используя ограничение, я пообещал, что не буду использовать alias range1 и range2, но как сделать то же самое для массива, объявленного внутри моей функции?

Ответ 1

Хотя ответ Джеффа прав, т.е. вы всегда можете сделать указатель на выделенный массив, факт заключается в том, что компилятор знает во время компиляции, что значения tmp не будут сглажены, потому что переменная объявлена ​​как фактический массив, не указатель. Единственные шансы на псевдоним массива - объявить указатель на него, поэтому, если вы этого не сделаете, нет необходимости объявлять его как restrict. Это более очевидно, если tmpvalues - единственная переменная, которую вы будете иметь в этой функции.

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

Документация, с которой я столкнулся, связана с C99:

Пусть D - объявление обычного идентификатора, обеспечивающего средство обозначение объекта P в качестве ограничивающего указателя указателя на тип T.

Обратите внимание, что это относится только к указателям.

В этом другом документе от TI приведены некоторые подсказки по настройке производительности с использованием ключевого слова restrict. В дополнение ко всем подсказкам в разделе 3.3 приведены примеры, когда можно применить этот тип классификатора, а когда нет. Ищите объявление массива x в середине страницы 16, он заявляет, что он не объявляет указатель и, следовательно, не может быть restrict -qualified.

Ответ 2

Почему вы не можете сделать следующее? Вы не получаете доступ к данным, связанным с tmpvalues через эту переменную, поэтому допустимо использовать указатель ограничения в вычислительной части кода.

#include <stdio.h>
#include <stdlib.h>

int heavy_calcs(int n, float* restrict range1, float* restrict range2)
{
    if (n>1000) return 1;
    float tmpvalues[1000] = {0};
    {
        float * restrict ptv = tmpvalues;
        for (int i=0; i<n; i++) {
            ptv[i] = range1[i] + range2[i];
        }
    }
    return 0;
}

int main(int argc, char * argv[])
{
    int n = (argc>1) ? atoi(argv[1]) : 1000;
    float * r1 = (float*)malloc(n*sizeof(float));
    float * r2 = (float*)malloc(n*sizeof(float));
    int rc = heavy_calcs(n,r1,r2);
    free(r1);
    free(r2);
    return rc;
}

Я запускал это через компилятор Intel 15, и он не испытывал проблем с векторизации цикла. Конечно, этот цикл является тривиальным по сравнению с тем, что я считаю вашим, поэтому ваш пробег может отличаться.