C语言中restrict关键字的用途和优化效果是什么?
restrict 关键字基本概念:
-
指针别名限制
cvoid copy(int *restrict dest, const int *restrict src, size_t n) { for (size_t i = 0; i < n; i++) { dest[i] = src[i]; } } // dest 和 src 不会指向重叠的内存区域 -
编译器优化
c// 没有 restrict void add_arrays(int *a, int *b, int *c, int n) { for (int i = 0; i < n; i++) { a[i] = b[i] + c[i]; } } // 使用 restrict void add_arrays_optimized(int *restrict a, const int *restrict b, const int *restrict c, int n) { for (int i = 0; i < n; i++) { a[i] = b[i] + c[i]; } }
使用场景:
-
内存拷贝
cvoid memcpy_custom(void *restrict dest, const void *restrict src, size_t n) { unsigned char *d = dest; const unsigned char *s = src; while (n--) { *d++ = *s++; } } -
数学运算
cvoid vector_add(double *restrict result, const double *restrict a, const double *restrict b, size_t size) { for (size_t i = 0; i < size; i++) { result[i] = a[i] + b[i]; } } -
字符串处理
csize_t strlen_custom(const char *restrict str) { size_t len = 0; while (*str++) len++; return len; }
优化效果:
-
循环展开
cvoid process(int *restrict data, int n) { // 编译器可以安全地展开循环 for (int i = 0; i < n; i++) { data[i] *= 2; } } -
向量化
cvoid scale_array(double *restrict arr, double factor, int n) { for (int i = 0; i < n; i++) { arr[i] *= factor; } // 编译器可以使用 SIMD 指令 } -
缓存优化
cvoid matrix_multiply(double *restrict result, const double *restrict a, const double *restrict b, int rows, int cols, int k) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { result[i * cols + j] = 0; for (int p = 0; p < k; p++) { result[i * cols + j] += a[i * k + p] * b[p * cols + j]; } } } }
注意事项:
-
未定义行为
cvoid dangerous(int *restrict a, int *restrict b) { *a = 10; *b = 20; // 如果 a 和 b 指向同一位置,行为未定义 } -
参数传递
cvoid function(int *restrict p) { // p 在函数内部不会产生别名 } int main() { int x = 10; function(&x); // 安全 } -
结构体指针
cstruct Point { int x, y; }; void transform(struct Point *restrict p) { p->x *= 2; p->y *= 2; }
实际应用示例:
-
图像处理
cvoid grayscale_image(unsigned char *restrict pixels, int width, int height) { for (int i = 0; i < width * height * 3; i += 3) { unsigned char gray = (pixels[i] + pixels[i+1] + pixels[i+2]) / 3; pixels[i] = pixels[i+1] = pixels[i+2] = gray; } } -
信号处理
cvoid apply_filter(double *restrict output, const double *restrict input, const double *restrict kernel, int size, int kernel_size) { for (int i = 0; i < size; i++) { output[i] = 0; for (int j = 0; j < kernel_size; j++) { if (i + j < size) { output[i] += input[i + j] * kernel[j]; } } } } -
数据压缩
cvoid compress_data(const int *restrict input, int *restrict output, int size) { int out_index = 0; int current = input[0]; int count = 1; for (int i = 1; i < size; i++) { if (input[i] == current) { count++; } else { output[out_index++] = current; output[out_index++] = count; current = input[i]; count = 1; } } }
性能对比:
-
无 restrict
cvoid add_slow(int *a, int *b, int *c, int n) { for (int i = 0; i < n; i++) { a[i] = b[i] + c[i]; } // 编译器必须考虑指针重叠 } -
有 restrict
cvoid add_fast(int *restrict a, const int *restrict b, const int *restrict c, int n) { for (int i = 0; i < n; i++) { a[i] = b[i] + c[i]; } // 编译器可以激进优化 }