noalias

Microsoft 固有の仕様

noalias は、関数呼び出しが表示可能なグローバル状態を変更または参照せず、ポインター パラメーター (第 1 レベルの間接参照) によって直接指定されるメモリのみを変更することを意味します。

関数が noalias として注釈が指定されている場合、オプティマイザーはパラメーター自体に加えてポインター パラメーターの第 1 レベルの間接参照のみが関数内で参照または変更されると仮定します。

注釈 noalias は、注釈付き関数の本体内でのみ適用されます。 関数を __declspec(noalias) としてマークしても、関数によって返されるポインターの別名には影響しません。

エイリアスに影響を与える可能性がある別の注釈については、「__declspec(restrict)」を参照してください。

次のコードは、__declspec(noalias) の使用例です。

メモリにアクセスする関数 multiply に注釈 __declspec(noalias) が付く場合、パラメーター リスト内のポインターを経由する場合を除き、この関数がグローバル状態を変更しないということがコンパイラに指示されます。

// declspec_noalias.c
#include <stdio.h>
#include <stdlib.h>

#define M 800
#define N 600
#define P 700

float * mempool, * memptr;

float * ma(int size)
{
    float * retval;
    retval = memptr;
    memptr += size;
    return retval;
}

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);
}

関連項目

__declspec
キーワード
__declspec(restrict)