你的原始代码对我来说很失败,比如:
void foo7(int n, double ARRAY_RESTRICT a[n], const double ARRAY_RESTRICT b[n], const double ARRAY_RESTRICT c[n])
^
restrict.c:126:1: error: invalid use of ârestrictâ
restrict.c:126:1: error: invalid use of ârestrictâ
restrict.c:145:1: error: invalid use of ârestrictâ
传输注释的选定部分
§6.7.6.3
函数声明器(包括原型)
具有示例5,其中说明以下函数原型声明器是等效的:
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);
这是标准中唯一一个限制与数组类型直接关联的地方。§6.7.6一般用于声明器,§6.7.6.2用于数组声明器,在我看来,限制必须出现在数组维度的第一个组件内。在您的环境中,它应该是:
void foo7(int n, double a[ARRAY_RESTRICT n],
const double b[ARRAY_RESTRICT n],
const double c[ARRAY_RESTRICT n])
如果没有看到标准中的示例,如果你问这个问题,我不会相信这个符号!请注意,这适用于阵列和VLA。
根据注释,该修订代码在相同的编译选项下进行了干净的编译:
gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -Wold-style-declaration -Werror -c new.restrict.c
编译选项要求预先声明非静态函数,因此声明位于文件顶部。我还强迫
#define ARRAY_RESTRICT restrict
而不是将其作为编译选项。
编译器是在Ubuntu 14.04衍生版本上运行的GCC 4.9.2。
文件
new.restrict.c
:
/* #define PRAGMA_SIMD _Pragma("simd") */
#define PRAGMA_SIMD
#ifdef __INTEL_COMPILER
#define ASSUME_ALIGNED(a) __assume_aligned(a, 64)
#else
#define ASSUME_ALIGNED(a)
#endif
#define ARRAY_RESTRICT restrict
#ifndef ARRAY_RESTRICT
#define ARRAY_RESTRICT
#endif
void foo1(double *restrict a, const double *restrict b, const double *restrict c);
void foo2(double *restrict a, const double *restrict b, const double *restrict c);
void foo3(int n, double *restrict a, const double *restrict b, const double *restrict c);
void foo4(int n, double *restrict a, const double *restrict b, const double *restrict c);
void foo5(double a[ARRAY_RESTRICT 2048], const double b[ARRAY_RESTRICT 2048], const double c[ARRAY_RESTRICT 2048]);
void foo6(double a[ARRAY_RESTRICT 2048], const double b[ARRAY_RESTRICT 2048], const double c[ARRAY_RESTRICT 2048]);
void foo7(int n, double a[ARRAY_RESTRICT n], const double b[ARRAY_RESTRICT n], const double c[ARRAY_RESTRICT n]);
void foo8(int n, double a[ARRAY_RESTRICT n], const double b[ARRAY_RESTRICT n], const double c[ARRAY_RESTRICT n]);
void foo1(double *restrict a, const double *restrict b, const double *restrict c)
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < 2048; ++i)
{
if (c[i] > 0)
{
a[i] = b[i];
}
else
{
a[i] = 0.0;
}
}
}
void foo2(double *restrict a, const double *restrict b, const double *restrict c)
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < 2048; ++i)
{
a[i] = ((c[i] > 0) ? b[i] : 0.0);
}
}
/* Undetermined size version */
void foo3(int n, double *restrict a, const double *restrict b, const double *restrict c)
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < n; ++i)
{
if (c[i] > 0)
{
a[i] = b[i];
}
else
{
a[i] = 0.0;
}
}
}
void foo4(int n, double *restrict a, const double *restrict b, const double *restrict c)
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < n; ++i)
{
a[i] = ((c[i] > 0) ? b[i] : 0.0);
}
}
/* Static array versions */
void foo5(double a[ARRAY_RESTRICT 2048], const double b[ARRAY_RESTRICT 2048], const double c[ARRAY_RESTRICT 2048])
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < 2048; ++i)
{
if (c[i] > 0)
{
a[i] = b[i];
}
else
{
a[i] = 0.0;
}
}
}
void foo6(double a[ARRAY_RESTRICT 2048], const double b[ARRAY_RESTRICT 2048], const double c[ARRAY_RESTRICT 2048])
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < 2048; ++i)
{
a[i] = ((c[i] > 0) ? b[i] : 0.0);
}
}
/* VLA versions */
void foo7(int n, double a[ARRAY_RESTRICT n], const double b[ARRAY_RESTRICT n], const double c[ARRAY_RESTRICT n])
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < n; ++i)
{
if (c[i] > 0)
{
a[i] = b[i];
}
else
{
a[i] = 0.0;
}
}
}
void foo8(int n, double a[ARRAY_RESTRICT n], const double b[ARRAY_RESTRICT n], const double c[ARRAY_RESTRICT n])
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < n; ++i)
{
a[i] = ((c[i] > 0) ? b[i] : 0.0);
}
}