chris@mimsy.UUCP (Chris Torek) (05/01/88)
[long quote] In article <270@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes: >most users of vector processors are surprised that the following function: > > void addvec(double a[], double b[], double c[], int n) { > int i; > > for (i = 0; i < n; i++) > a[i] = b[i] + c[i]; > } > >does not result in a single vector addition (especially since writing the >"same" function in FORTRAN does). Actually, "angry" is probably a better >term that "surprised" in this case. The reason for this is, of course, that >in C there is nothing wrong with calling this function like: > > addvec(a+1, a, a+1, sizeof a / sizeof a[0] - 1); > >which sums the vector into its last element. This is invalid in FORTRAN >which is why the FORTRAN version can vectorize but the C version can't. I would like to mention that while something like CALL ADDVEC(A(2), A(1), A(2), N - 1) is technically illegal given a SUBROUTINE ADDVEC as defined above, transliterated to F77, most compilers would never notice this. The call would behave on scalar machines and do something odd on vector machines. This sort of thing does happen, and I doubt not that (say) Convex (who have vector-reducing F77 and C compilers) get bug reports from irate users demanding that the compiler be fixed, when in fact it is the users' programs that are broken. One might think `I wrote a loop, not a vector instruction'---and in a language like C, this claim has far more weight than in a higher level language such as FP or Prolog. Indeed, given _builtin functions, one might note that a reasonably portable vector application could be written without `noalias'. Consider the following: #include "vector.h" ... vec_addD3(a, b, c, VEC_N_ELEM(c)); vec_mulD2(c, b, VEC_N_ELEM(c)); ... $ cc main.c vecsupport.c Now look at `vector.h': /* get the configuration information */ #include "vec_config.h" #define VEC_N_ELEM(x) (sizeof(x) / sizeof(*(x))) #ifdef VEC_NONE /* use simulation library */ #define VEC_3ADDRESS #endif #if defined(VEC_3ADDRESS) /* all built-in vectors are three-address-code versions */ #define vec_addF2(a, b, n) vec_addF3(a, b, b, n) #define vec_addD2(a, b, n) vec_addD3(a, b, b, n) #define vec_mulF2(a, b, n) vec_mulF3(a, b, b, n) #define vec_mulD2(a, b, n) vec_mulD3(a, b, b, n) ... #else void vec_addF2(float a[], float b[], size_t n); void vec_addD2(double a[], double b[], size_t n); ... #endif ... #ifdef VEC_NONE void vec_addF3(float a[], float b[], float c[], size_t n) void vec_addD3(double a[], double b[], double c[], size_t n) void vec_mulF3(float a[], float b[], float c[], size_t n) ... #else /* builtin versions figure type for themselves */ #define vec_addF3(a, b, c, n) _builtin_vec_add(a, b, c, n) #define vec_addD3(a, b, c, n) _builtin_vec_add(a, b, c, n) #define vec_mulF3(a, b, c, n) _builtin_vec_mul(a, b, c, n) ... The greatest problem with this system is the necessity for applying the proper type to the vector sum. The C++ language can do this automatically; indeed, with the proper class definitions, and a bit of operator overloading, one can simply write c = a + b; // vector sum Perhaps, now that everyone is jumping on the C bandwagon, we should aim the number crunching folk at C++ instead. Tell them `It is just like C, except that you can write matrix operations directly.' Perhaps that will win them over. :-) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris