Использование ограничений с массивами?
Есть ли способ сказать компилятору 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, и он не испытывал проблем с векторизации цикла. Конечно, этот цикл является тривиальным по сравнению с тем, что я считаю вашим, поэтому ваш пробег может отличаться.