Restrict указатели

Теги: си, указатели, restrict, restrict pointer



Ключевое слово restrict

Restrict указатели – это служебное слово в языке с (начиная с версии 99) с помощью которого программист может указать компилятору, что указатель ссылается на область памяти, на которую больше никакой указатель не ссылается. Это позволяет компилятору генерировать более оптимизированный код. Использование restrict определено только для указателей (иначе, это просто не повлияет на сгенерированный код). Рассмотрим простой пример:

#include <stdio.h>

void setValues(int *a, int *b, int *value) {
	*a += *value;
	*b += *value;
}

int main (int argc, char **argv) {
	int a = 0, b = 0, c = 555;
	
	setValues(&a, &b, &c);
	printf("a = %d, b = %d", a, b);
	
	return 0;
}

Функция setValues принимает три указателя и нам заранее известно, что они никогда не указывают на одну и ту же область памяти (нам это известно из всего кода, включаю функцию main). Поэтому функция может объявить аргументы функции как restrict

#include <stdio.h>

void setValues(int *restrict a, int *restrict b, int *restrict value) {
	*a += *value;
	*b += *value;
}

int main (int argc, char **argv) {
	int our = 0;
	int *a = &our, *b = &our, c = 555;
	
	setValues(a, b, &c);
	printf("a = %d, b = %d", *a, *b);
	
	return 0;
}

Посмотрим на различие в сгенерированном коде. Для первого

0000001b <_setValues>:
  1b:   53                      push   %ebx
  1c:   8b 4c 24 08          	mov    0x8(%esp),%ecx
  20:   8b 44 24 0c          	mov    0xc(%esp),%eax
  24:   8b 54 24 10          	mov    0x10(%esp),%edx
  28:   8b 1a                	mov    (%edx),%ebx
  2a:   01 19                	add    %ebx,(%ecx)
  2c:   8b 12                	mov    (%edx),%edx
  2e:   01 10                   add    %edx,(%eax)
  30:   5b                      pop    %ebx
  31:   c3                      ret

И для второго случая

0000001b <_setValues>:
  1b:	8b 4c 24 04          	mov    0x4(%esp),%ecx
  1f:	8b 44 24 08          	mov    0x8(%esp),%eax
  23:	8b 54 24 0c          	mov    0xc(%esp),%edx
  27:	8b 12                	mov    (%edx),%edx
  29:	01 11                	add    %edx,(%ecx)
  2b:	01 10                	add    %edx,(%eax)
  2d:	c3                   	ret    

В реальности, использование restrict может даль существенный прирост производительности за счёт исключения дополнительного обращения к памяти (в данном примере этого, к сожалению не видно). Тем не менее, это сильно зависит от архитектуры, версии компилятора и пр.

Q&A

Всё ещё не понятно? – пиши вопросы на ящик email
Встраиваемые функции