noalias
Specifické pro Microsoft
noalias znamená, že volání funkce neupravuje nebo neodkazuje na globální stav a pouze upravuje paměť odkazovanou na directly parametry ukazatele (nepřímé odkazování první úrovně).
Pokud je funkce označena jako noalias, optimalizér může předpokládat, že kromě parametrů samotných, jsou odkazovány pouze nepřímá odkazování parametrů ukazatele nebo jsou upraveny uvnitř funkce.Stav globální viditelnosti je sada všech dat, která nejsou definována nebo odkazována mimo rozsah kompilace a jejich adresa není přebrána.Obor kompilace jsou všechny zdrojové soubory (sestavení /LTCG (vytváření kódu v době propojování)) nebo jeden zdrojový soubor (sestavení mimo /LTCG).
Příklad
Následující příklad ukazuje použití __declspec(restrict) a __declspec(noalias).Za normálních okolností je paměť vrácena z mallocrestrict a noalias, protože záhlaví CRT jsou odpovídajícím způsobem upravena.
Nicméně v tomto případě platí, že ukazatelé mempool a memptr jsou globální, a tedy kompilátor nemá žádnou záruku, že paměť není předmětem aliasu.Upravení funkcí, které vracejí ukazatele s __declspec(restrict) informuje kompilátor, že paměť, na kterou je odkazováno návratovou hodnotou, není aliasována.
Upravení funkce, která v tomto příkladu přistupuje do paměti pomocí __declspec(noalias) sděluje kompilátoru, že se tato funkce neovlivňuje s globálním stavem, s výjimkou ukazatelů jejího seznamu parametrů.
// declspec_noalias.c
#include <stdio.h>
#include <stdlib.h>
#define M 800
#define N 600
#define P 700
float * mempool, * memptr;
__declspec(restrict) float * ma(int size)
{
float * retval;
retval = memptr;
memptr += size;
return retval;
}
__declspec(restrict) float * init(int m, int n)
{
float * a;
int i, j;
int k=1;
a = ma(m * n);
if (!a) exit(1);
for (i=0; i<m; i++)
for (j=0; j<n; j++)
a[i*n+j] = 0.1/k++;
return a;
}
__declspec(noalias) void multiply(float * a, float * b, float * c)
{
int i, j, k;
for (j=0; j<P; j++)
for (i=0; i<M; i++)
for (k=0; k<N; k++)
c[i * P + j] =
a[i * N + k] *
b[k * P + j];
}
int main()
{
float * a, * b, * c;
mempool = (float *) malloc(sizeof(float) * (M*N + N*P + M*P));
if (!mempool)
{
puts("ERROR: Malloc returned null");
exit(1);
}
memptr = mempool;
a = init(M, N);
b = init(N, P);
c = init(M, P);
multiply(a, b, c);
}