mot clé "restrict"

mot clé "restrict" - C - Programmation

Marsh Posté le 14-08-2003 à 21:11:45    

Hello
 
Je viens de réaliser que le mot clé restrict est pas mal utilisé dans la librairie standard, et je me demandais à quoi il servait.  
 
J'ai rien pigé au chapitre de la norme là-dessus, et impossible de trouver quelque chose en français !
 
Y-aurait-il une bonne âme pour m'expliquer ça ?
 
Merci !

Reply

Marsh Posté le 14-08-2003 à 21:11:45   

Reply

Marsh Posté le 14-08-2003 à 22:08:12    

:heink: ou t'as vu le mot clef « restrict » dans la norme ?

Reply

Marsh Posté le 14-08-2003 à 22:18:24    

Taz a écrit :

:heink: ou t'as vu le mot clef « restrict » dans la norme ?

6.7.3.1

Reply

Marsh Posté le 14-08-2003 à 22:26:22    

tiens il est pas dans le K&R ... c'est bizarre ça, c'est pour ça que je demandais ... mais dans le draft il y est  
 
 
   [:spamafote]

Reply

Marsh Posté le 14-08-2003 à 22:29:46    

évidemment ...  

Citation :

Several keywords were added in C89: const, enum, signed, void and volatile. New in C9X are the keywords inline, restrict, _Bool, _Complex and _Imaginary.

j'aurais parier que c'était ANSI
 
leneuf22 > tu veux que je te colle l'intégralité de la défintion en anglais ou tu parles de cette même documentation ?

Reply

Marsh Posté le 14-08-2003 à 22:35:26    

Bah j'ai déjà la norme en anglais et j'y ai rien capté, ni à la définition et encore moins à l'utilité...
 
Si ça peut me permettre de comprendre, je veux bien !
Sinon si quelqu'un à quelque chose en français ça serait pas mal aussi.

Reply

Marsh Posté le 14-08-2003 à 22:37:32    

tu as le draft ou le rationale ? il me semble que le rationale est plus clair?

Reply

Marsh Posté le 14-08-2003 à 22:45:45    

Heu, excuse mon ignorance, mais le draft et le rationale, c'est des bouquins ?
 
Si oui bah j'en ai aucun des 2...

Reply

Marsh Posté le 14-08-2003 à 22:49:54    

tu as quoi? restrict est nouveau du C99. tu as un libre sur le C99? tu t'es payé le bouquin du commité ISO?

Reply

Marsh Posté le 14-08-2003 à 22:52:22    

Citation :

6.7.3.1 Formal definition of restrict
 
1 Let D be a declaration of an ordinary identifier that provides a means of designating an
object P as a restrict-qualified pointer to type T.
 
2 If D appears inside a block and does not have storage class extern, let B denote the
block. If D appears in the list of parameter declarations of a function definition, let B
denote the associated block. Otherwise, let B denote the block of main (or the block of
whatever function is called at program startup in a freestanding environment).
 
3 In what follows, a pointer expression E is said to be based on object P if (at some
sequence point in the execution of B prior to the evaluation of E) modifying P to point to
a copy of the array object into which it formerly pointed would change the value of E.117)
Note that ??based?? is defined only for expressions with pointer types.
 
4 During each execution of B, let L be any lvalue that has &L based on P. If L is used to
access the value of the object X that it designates, and X is also modified (by any means),
then the following requirements apply: T shall not be const-qualified. Every other lvalue
used to access the value of X shall also have its address based on P. Every access that
modifies X shall be considered also to modify P, for the purposes of this subclause. If P
is assigned the value of a pointer expression E that is based on another restricted pointer
object P2, associated with block B2, then either the execution of B2 shall begin before
the execution of B, or the execution of B2 shall end prior to the assignment. If these
requirements are not met, then the behavior is undefined.
 
5 Here an execution of B means that portion of the execution of the program that would
correspond to the lifetime of an object with scalar type and automatic storage duration
associated with B.
 
6 A translator is free to ignore any or all aliasing implications of uses of restrict.
 
7 EXAMPLE 1 The file scope declarations
 

Code :
  1. int * restrict a;
  2. int * restrict b;
  3. extern int c[];


assert that if an object is accessed using one of a, b, or c, and that object is modified anywhere in the
program, then it is never accessed using either of the other two.
 
8 EXAMPLE 2 The function parameter declarations in the following example

Code :
  1. void f(int n, int * restrict p, int * restrict q)
  2. {
  3. while (n-- > 0)
  4. *p++ = *q++;
  5. }


assert that, during each execution of the function, if an object is accessed through one of the pointer
parameters, then it is not also accessed through the other.
 
9 The benefit of the restrict qualifiers is that they enable a translator to make an effective dependence
analysis of function f without examining any of the calls of f in the program. The cost is that the
programmer has to examine all of those calls to ensure that none give undefined behavior. For example, the
second call of f in g has undefined behavior because each of d[1] through d[49] is accessed through
both p and q.

Code :
  1. void g(void)
  2. {
  3. extern int d[100];
  4. f(50, d + 50, d); // valid
  5. f(50, d + 1, d); // undefined behavior
  6. }


 
10 EXAMPLE 3 The function parameter declarations

Code :
  1. void h(int n, int * restrict p, int * restrict q, int * restrict r)
  2. {
  3. int i;
  4. for (i = 0; i < n; i++)
  5. p[i] = q[i] + r[i];
  6. }


illustrate how an unmodified object can be aliased through two restricted pointers. In particular, if a and b
are disjoint arrays, a call of the form h(100, a, b, b) has defined behavior, because array b is not
modified within function h.
11 EXAMPLE 4 The rule limiting assignments between restricted pointers does not distinguish between a
function call and an equivalent nested block. With one exception, only ??outer-to-inner?? assignments
between restricted pointers declared in nested blocks have defined behavior.

Code :
  1. {
  2. int * restrict p1;
  3. int * restrict q1;
  4. p1 = q1; // undefined behavior
  5. {
  6. int * restrict p2 = p1; // valid
  7. int * restrict q2 = q1; // valid
  8. p1 = q2; // undefined behavior
  9. p2 = q2; // undefined behavior
  10. }
  11. }


Reply

Marsh Posté le 14-08-2003 à 22:52:22   

Reply

Marsh Posté le 14-08-2003 à 22:55:45    

le rationale  
 

Citation :

restrict Objects referenced through a restrict-qualified pointer have a special association with that pointer. All references to that object must directly or indirectly use the value of this pointer. In the absence of this qualifier, other pointers can alias this object. Cacheing the value in an object designated through a restrict-qualified pointer is safe at the beginning of the block in which the pointer is declared, because no pre-existing aliases may also be used to reference 40 that object. The cached value must be restored to the object by the end of the block, where pre-existing aliases again become available. New aliases may be formed within the block, but these must all depend on the value of the restrictqualified pointer, so that they can be identified and adjusted to refer to the cached value. For a restrict-qualified pointer at file scope, the block is the body of 45 main.


 
et
 
 

Citation :

68 6.7.3.1 Formal definition of restrict A new feature of C9X: The restrict type qualifier allows programs to be written so that translators can produce significantly faster executables. Anyone for whom this is not a concern can safely ignore this feature of the language. 20 The problem that the restrict qualifier addresses is that potential aliasing can inhibit optimizations. Specifically, if a translator cannot determine that two different pointers are being used to reference different objects, then it cannot apply optimizations such as maintaining the values of the objects in registers rather than in memory, or reordering loads and stores of these values. This problem can have a significant effect on a program that, for example, performs 25 arithmetic calculations on large arrays of numbers. The effect can be measured by comparing a program that uses pointers with a similar program that uses file scope arrays (or with a similar Fortran program). The array version can run faster by a factor of ten or more on a system with vector processors. Where such large performance gains are possible, implementations have of course offered their own solutions, usually in the form of compiler directives that specify particular 30 optimizations. Differences in the spelling, scope, and precise meaning of these directives have made them troublesome to use in a program that must run on many different systems. This was the motivation for a standard solution. The restrict qualifier was designed to express and extend two types of aliasing information 35 already specified in the language. First, if a single pointer is directly assigned the return value from an invocation of malloc, then that pointer is the sole initial means of access to the allocated object (that is, another pointer can gain access to that object only by being assigned a value that is based on the value of the first 40 pointer). Declaring the pointer to be restrict-qualified expresses this information to a translator. Furthermore, the qualifier can be used to extend a translator s special treatment of such a pointer to more general situations. For example, an invocation of malloc might be hidden from the translator in another function, or a single invocation of malloc might be used to allocate several objects, each referenced through its own pointer. 45 C9X RATIONALE WG14/N897 J11/99-032 69 Second, the library specifies two versions of an object copying function, because on many systems a faster copy is possible if it is known that the source and target arrays do not overlap. The restrict qualifier can be used to express the restriction on overlap in a new prototype that is compatible with the original version: 5 void *memcpy(void * restrict s1, const void * restrict s2, size_t n); void *memmove(void * s1, const void * s2, size_t n); With the restriction visible to a translator, a straightforward implementation of memcpy in C can 10 now give a level of performance that previously required assembly language or other non-standard means. Thus the restrict qualifier provides a standard means with which to make, in the definition of any function, an aliasing assertion of a type that could previously be made only for library functions. 15 The complexity of the specification of the restrict qualifier reflects the fact that C has a rich set of types and a dynamic notion of the type of an object. Recall, for example, that an object does not have a fixed type, but acquires a type when referenced. Similarly, in some of the library functions, the extent of an array object referenced through a pointer parameter is dynamically determined, either by another parameter or by the contents of the array. 20 The full specification is necessary to determine the precise meaning of a qualifier in any context, and so must be understood by compiler implementors. Fortunately, most others will need to understand only a few simple patterns of usage explained in the following examples. 25 A translator can assume that a file scope restrict-qualified pointer is the sole initial means of access to an object, much as if it were the declared name of an array. This is useful for a dynamically allocated array whose size is not known until run time. Note in the example how a single block of storage is effectively subdivided into two disjoint objects. 30 float * restrict a1, * restrict a2; void init(int n) { float * t = malloc(2 * n * sizeof(float)); 35 a1 = t; // a1 refers to 1st half a2 = t + n; // a2 refers to 2nd half } A translator can assume that a restrict-qualified pointer that is a function parameter is, at the 40 beginning of each execution of the function, the sole means of access to an object. Note that this assumption expires with the end of each execution. In the following example, parameters a1 and a2 can be assumed to refer to disjoint array objects because both are restrict-qualified. This implies that each iteration of the loop is independent of the others, and so the loop can be aggressively optimized. 45 WG14/N897 J11/99-032 C9X RATIONALE 70 void f1(int n, float * restrict a1, const float * restrict a2) { int i; for ( i = 0; i < n; i++ ) 5 a1[i] += a2[i]; } A translator can assume that a restrict-qualified pointer declared with block scope is, during each execution of the block, the sole initial means of access to an object. An invocation of the 10 macro shown in the following example is equivalent to an inline version of a call to the function f1 above. # define f2(N,A1,A2) \ { int n = (N); \ 15 float * restrict a1 = (A1); \ float * restrict a2 = (A2); \ int i; \ for ( i = 0; i < n; i++ ) \ a1[i] += a2[i]; \ 20 } The restrict qualifier can be used in the declaration of a structure member. A translator can assume, when an identifier is declared that provides a means of access to an object of that structure type, that the member provides the sole initial means of access to an object of the type specified in 25 the member declaration. The duration of the assumption depends on the scope of the identifier, not on the scope of the declaration of the structure. Thus a translator can assume that s1.a1 and s1.a2 below are used to refer to disjoint objects for the duration of the whole program, but that s2.a1 and s2.a2 are used to refer to disjoint objects only for the duration of each invocation of the f3 function. 30 struct t { int n; float * restrict a1, * restrict a2; }; 35 struct t s1; void f3(struct t s2) { /* ... */ } 40 The meaning of the restrict qualifier for a union member or in a type definition is analogous. Just as an object with a declared name can be aliased by an unqualified pointer, so can the object associated with a restrict-qualified pointer. The restrict qualifier is therefore unlike the register storage class, which precludes such aliasing. 45 This allows the restrict qualifier to be introduced more easily into existing programs, and also allows restrict to be used in new programs that call functions from libraries that do not use C9X RATIONALE WG14/N897 J11/99-032 the qualifier. In particular, a restrict-qualified pointer can be the actual argument for a function parameter that is unqualified. On the other hand, it is easier for a translator to find opportunities for optimization if as many as possible of the pointers in a program are restrictqualified.68 6.7.3.1 Formal definition of restrict A new feature of C9X: The restrict type qualifier allows programs to be written so that translators can produce significantly faster executables. Anyone for whom this is not a concern can safely ignore this feature of the language. 20 The problem that the restrict qualifier addresses is that potential aliasing can inhibit optimizations. Specifically, if a translator cannot determine that two different pointers are being used to reference different objects, then it cannot apply optimizations such as maintaining the values of the objects in registers rather than in memory, or reordering loads and stores of these values. This problem can have a significant effect on a program that, for example, performs 25 arithmetic calculations on large arrays of numbers. The effect can be measured by comparing a program that uses pointers with a similar program that uses file scope arrays (or with a similar Fortran program). The array version can run faster by a factor of ten or more on a system with vector processors. Where such large performance gains are possible, implementations have of course offered their own solutions, usually in the form of compiler directives that specify particular 30 optimizations. Differences in the spelling, scope, and precise meaning of these directives have made them troublesome to use in a program that must run on many different systems. This was the motivation for a standard solution. The restrict qualifier was designed to express and extend two types of aliasing information 35 already specified in the language. First, if a single pointer is directly assigned the return value from an invocation of malloc, then that pointer is the sole initial means of access to the allocated object (that is, another pointer can gain access to that object only by being assigned a value that is based on the value of the first 40 pointer). Declaring the pointer to be restrict-qualified expresses this information to a translator. Furthermore, the qualifier can be used to extend a translator s special treatment of such a pointer to more general situations. For example, an invocation of malloc might be hidden from the translator in another function, or a single invocation of malloc might be used to allocate several objects, each referenced through its own pointer. 45 C9X RATIONALE WG14/N897 J11/99-032 69 Second, the library specifies two versions of an object copying function, because on many systems a faster copy is possible if it is known that the source and target arrays do not overlap. The restrict qualifier can be used to express the restriction on overlap in a new prototype that is compatible with the original version: 5 void *memcpy(void * restrict s1, const void * restrict s2, size_t n); void *memmove(void * s1, const void * s2, size_t n); With the restriction visible to a translator, a straightforward implementation of memcpy in C can 10 now give a level of performance that previously required assembly language or other non-standard means. Thus the restrict qualifier provides a standard means with which to make, in the definition of any function, an aliasing assertion of a type that could previously be made only for library functions. 15 The complexity of the specification of the restrict qualifier reflects the fact that C has a rich set of types and a dynamic notion of the type of an object. Recall, for example, that an object does not have a fixed type, but acquires a type when referenced. Similarly, in some of the library functions, the extent of an array object referenced through a pointer parameter is dynamically determined, either by another parameter or by the contents of the array. 20 The full specification is necessary to determine the precise meaning of a qualifier in any context, and so must be understood by compiler implementors. Fortunately, most others will need to understand only a few simple patterns of usage explained in the following examples. 25 A translator can assume that a file scope restrict-qualified pointer is the sole initial means of access to an object, much as if it were the declared name of an array. This is useful for a dynamically allocated array whose size is not known until run time. Note in the example how a single block of storage is effectively subdivided into two disjoint objects. 30 float * restrict a1, * restrict a2; void init(int n) { float * t = malloc(2 * n * sizeof(float)); 35 a1 = t; // a1 refers to 1st half a2 = t + n; // a2 refers to 2nd half } A translator can assume that a restrict-qualified pointer that is a function parameter is, at the 40 beginning of each execution of the function, the sole means of access to an object. Note that this assumption expires with the end of each execution. In the following example, parameters a1 and a2 can be assumed to refer to disjoint array objects because both are restrict-qualified. This implies that each iteration of the loop is independent of the others, and so the loop can be aggressively optimized. 45 WG14/N897 J11/99-032 C9X RATIONALE 70 void f1(int n, float * restrict a1, const float * restrict a2) { int i; for ( i = 0; i < n; i++ ) 5 a1[i] += a2[i]; } A translator can assume that a restrict-qualified pointer declared with block scope is, during each execution of the block, the sole initial means of access to an object. An invocation of the 10 macro shown in the following example is equivalent to an inline version of a call to the function f1 above. # define f2(N,A1,A2) \ { int n = (N); \ 15 float * restrict a1 = (A1); \ float * restrict a2 = (A2); \ int i; \ for ( i = 0; i < n; i++ ) \ a1[i] += a2[i]; \ 20 } The restrict qualifier can be used in the declaration of a structure member. A translator can assume, when an identifier is declared that provides a means of access to an object of that structure type, that the member provides the sole initial means of access to an object of the type specified in 25 the member declaration. The duration of the assumption depends on the scope of the identifier, not on the scope of the declaration of the structure. Thus a translator can assume that s1.a1 and s1.a2 below are used to refer to disjoint objects for the duration of the whole program, but that s2.a1 and s2.a2 are used to refer to disjoint objects only for the duration of each invocation of the f3 function. 30 struct t { int n; float * restrict a1, * restrict a2; }; 35 struct t s1; void f3(struct t s2) { /* ... */ } 40 The meaning of the restrict qualifier for a union member or in a type definition is analogous. Just as an object with a declared name can be aliased by an unqualified pointer, so can the object associated with a restrict-qualified pointer. The restrict qualifier is therefore unlike the register storage class, which precludes such aliasing. 45 This allows the restrict qualifier to be introduced more easily into existing programs, and also allows restrict to be used in new programs that call functions from libraries that do not use C9X RATIONALE WG14/N897 J11/99-032 the qualifier. In particular, a restrict-qualified pointer can be the actual argument for a function parameter that is unqualified. On the other hand, it is easier for a translator to find opportunities for optimization if as many as possible of the pointers in a program are restrictqualified.

 
 
on va retenir essentiellement le  

Citation :

A new feature of C9X: The restrict type qualifier allows programs to be written so that translators can produce significantly faster executables. Anyone for whom this is not a concern can safely ignore this feature of the language.


 
 
edit: il a du mal mot collé depuis Acrobat Reader


Message édité par Taz le 14-08-2003 à 22:56:23
Reply

Marsh Posté le 14-08-2003 à 22:56:01    

Bah non, j'ai tout simplement le pdf de la norme C99 :
http://www.nirvani.net/docs/ansi_c.pdf
 
Chapitre 6.7.3.1 il y a le mot-clé restrict...

Reply

Marsh Posté le 14-08-2003 à 22:57:08    

ok, c'est le draft.

Reply

Marsh Posté le 14-08-2003 à 22:58:41    

Taz a écrit :

edit: il a du mal mot collé depuis Acrobat Reader

Moi je l'ai fais depuis le reader aussi et ça a bien fonctionné, la différence c'est que moi j'suis sous Windows (powaa) :D

Reply

Marsh Posté le 14-08-2003 à 22:59:23    

enfin bon, je crois que mon dernier quote est le plus important.

Reply

Marsh Posté le 14-08-2003 à 23:02:56    

en clair: c'est pour dire au traducteur/compilateur que tes pointeurs ne sont pas des alias vers le meme objet ce qui peux eventuellement permettre de meilleurs optimisations. ya plein de nouveautés comme ça dans le C99, pas très importante sauf pour ceux qui font de l'embarqué ou du calcul vectoriel, bref pas franchement utilisés pas le commun des mortels. mais si tu vois
 

Code :
  1. void f(void * restrict, void * restrict)

tu sais déjà que tout appel f(&truc, &truc) va sans doute produire un comportement indéfini

Reply

Marsh Posté le 14-08-2003 à 23:08:53    

edit (trop lent) : ok, merci pour l'explication !


Message édité par leneuf22 le 14-08-2003 à 23:09:52
Reply

Marsh Posté le 14-08-2003 à 23:27:51    

donc, il est très sur d'oublier tout ça... juste connaître histoire de tilter quand on tombe le-dessus [:spamafote]

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed