see http://mbed.org/users/no2chem/notebook/mbed-clock-control--benchmarks/

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers core_matrix.c Source File

core_matrix.c

00001 /*
00002 Author : Shay Gal-On, EEMBC
00003 
00004 This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 
00005 All rights reserved.                            
00006 
00007 EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
00008 CoreMark License that is distributed with the official EEMBC COREMARK Software release. 
00009 If you received this EEMBC CoreMark Software without the accompanying CoreMark License, 
00010 you must discontinue use and download the official release from www.coremark.org.  
00011 
00012 Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, 
00013 make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
00014 
00015 EEMBC 
00016 4354 Town Center Blvd. Suite 114-200
00017 El Dorado Hills, CA, 95762 
00018 */ 
00019 #include "coremark.h"
00020 /*
00021 Topic: Description
00022     Matrix manipulation benchmark
00023     
00024     This very simple algorithm forms the basis of many more complex algorithms. 
00025     
00026     The tight inner loop is the focus of many optimizations (compiler as well as hardware based) 
00027     and is thus relevant for embedded processing. 
00028     
00029     The total available data space will be divided to 3 parts:
00030     NxN Matrix A - initialized with small values (upper 3/4 of the bits all zero).
00031     NxN Matrix B - initialized with medium values (upper half of the bits all zero).
00032     NxN Matrix C - used for the result.
00033 
00034     The actual values for A and B must be derived based on input that is not available at compile time.
00035 */
00036 ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
00037 ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
00038 void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
00039 void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
00040 void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
00041 void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
00042 void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
00043 
00044 #define matrix_test_next(x) (x+1)
00045 #define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff)
00046 #define matrix_big(x) (0xf000 | (x))
00047 #define bit_extract(x,from,to) (((x)>>(from)) & (~(0xffffffff << (to))))
00048 
00049 #if CORE_DEBUG
00050 void printmat(MATDAT *A, ee_u32 N, char *name) {
00051     ee_u32 i,j;
00052     ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
00053     for (i=0; i<N; i++) {
00054         for (j=0; j<N; j++) {
00055             if (j!=0)
00056                 ee_printf(",");
00057             ee_printf("%d",A[i*N+j]);
00058         }
00059         ee_printf("\n");
00060     }
00061 }
00062 void printmatC(MATRES *C, ee_u32 N, char *name) {
00063     ee_u32 i,j;
00064     ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
00065     for (i=0; i<N; i++) {
00066         for (j=0; j<N; j++) {
00067             if (j!=0)
00068                 ee_printf(",");
00069             ee_printf("%d",C[i*N+j]);
00070         }
00071         ee_printf("\n");
00072     }
00073 }
00074 #endif
00075 /* Function: core_bench_matrix
00076     Benchmark function
00077 
00078     Iterate <matrix_test> N times, 
00079     changing the matrix values slightly by a constant amount each time.
00080 */
00081 ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) {
00082     ee_u32 N=p->N;
00083     MATRES *C=p->C;
00084     MATDAT *A=p->A;
00085     MATDAT *B=p->B;
00086     MATDAT val=(MATDAT)seed;
00087 
00088     crc=crc16(matrix_test(N,C,A,B,val),crc);
00089 
00090     return crc;
00091 }
00092 
00093 /* Function: matrix_test
00094     Perform matrix manipulation.
00095 
00096     Parameters:
00097     N - Dimensions of the matrix.
00098     C - memory for result matrix.
00099     A - input matrix
00100     B - operator matrix (not changed during operations)
00101 
00102     Returns:
00103     A CRC value that captures all results calculated in the function.
00104     In particular, crc of the value calculated on the result matrix 
00105     after each step by <matrix_sum>.
00106 
00107     Operation:
00108     
00109     1 - Add a constant value to all elements of a matrix.
00110     2 - Multiply a matrix by a constant.
00111     3 - Multiply a matrix by a vector.
00112     4 - Multiply a matrix by a matrix.
00113     5 - Add a constant value to all elements of a matrix.
00114 
00115     After the last step, matrix A is back to original contents.
00116 */
00117 ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) {
00118     ee_u16 crc=0;
00119     MATDAT clipval=matrix_big(val);
00120 
00121     matrix_add_const(N,A,val); /* make sure data changes  */
00122 #if CORE_DEBUG
00123     printmat(A,N,"matrix_add_const");
00124 #endif
00125     matrix_mul_const(N,C,A,val);
00126     crc=crc16(matrix_sum(N,C,clipval),crc);
00127 #if CORE_DEBUG
00128     printmatC(C,N,"matrix_mul_const");
00129 #endif
00130     matrix_mul_vect(N,C,A,B);
00131     crc=crc16(matrix_sum(N,C,clipval),crc);
00132 #if CORE_DEBUG
00133     printmatC(C,N,"matrix_mul_vect");
00134 #endif
00135     matrix_mul_matrix(N,C,A,B);
00136     crc=crc16(matrix_sum(N,C,clipval),crc);
00137 #if CORE_DEBUG
00138     printmatC(C,N,"matrix_mul_matrix");
00139 #endif
00140     matrix_mul_matrix_bitextract(N,C,A,B);
00141     crc=crc16(matrix_sum(N,C,clipval),crc);
00142 #if CORE_DEBUG
00143     printmatC(C,N,"matrix_mul_matrix_bitextract");
00144 #endif
00145     
00146     matrix_add_const(N,A,-val); /* return matrix to initial value */
00147     return crc;
00148 }
00149 
00150 /* Function : matrix_init
00151     Initialize the memory block for matrix benchmarking.
00152 
00153     Parameters:
00154     blksize - Size of memory to be initialized.
00155     memblk - Pointer to memory block.
00156     seed - Actual values chosen depend on the seed parameter.
00157     p - pointers to <mat_params> containing initialized matrixes.
00158 
00159     Returns:
00160     Matrix dimensions.
00161     
00162     Note:
00163     The seed parameter MUST be supplied from a source that cannot be determined at compile time
00164 */
00165 ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) {
00166     ee_u32 N=0;
00167     MATDAT *A;
00168     MATDAT *B;
00169     ee_s32 order=1;
00170     MATDAT val;
00171     ee_u32 i=0,j=0;
00172     if (seed==0)
00173         seed=1;
00174     while (j<blksize) {
00175         i++;
00176         j=i*i*2*4;      
00177     }
00178     N=i-1;
00179     A=(MATDAT *)align_mem(memblk);
00180     B=A+N*N;
00181 
00182     for (i=0; i<N; i++) {
00183         for (j=0; j<N; j++) {
00184             seed = ( ( order * seed ) % 65536 );
00185             val = (seed + order);
00186             val=matrix_clip(val,0);
00187             B[i*N+j] = val;
00188             val =  (val + order);
00189             val=matrix_clip(val,1);
00190             A[i*N+j] = val;
00191             order++;
00192         }
00193     }
00194 
00195     p->A=A;
00196     p->B=B;
00197     p->C=(MATRES *)align_mem(B+N*N);
00198     p->N=N;
00199 #if CORE_DEBUG
00200     printmat(A,N,"A");
00201     printmat(B,N,"B");
00202 #endif
00203     return N;
00204 }
00205 
00206 /* Function: matrix_sum
00207     Calculate a function that depends on the values of elements in the matrix.
00208 
00209     For each element, accumulate into a temporary variable.
00210     
00211     As long as this value is under the parameter clipval, 
00212     add 1 to the result if the element is bigger then the previous.
00213     
00214     Otherwise, reset the accumulator and add 10 to the result.
00215 */
00216 ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) {
00217     MATRES tmp=0,prev=0,cur=0;
00218     ee_s16 ret=0;
00219     ee_u32 i,j;
00220     for (i=0; i<N; i++) {
00221         for (j=0; j<N; j++) {
00222             cur=C[i*N+j];
00223             tmp+=cur;
00224             if (tmp>clipval) {
00225                 ret+=10;
00226                 tmp=0;
00227             } else {
00228                 ret += (cur>prev) ? 1 : 0;
00229             }
00230             prev=cur;
00231         }
00232     }
00233     return ret;
00234 }
00235 
00236 /* Function: matrix_mul_const
00237     Multiply a matrix by a constant.
00238     This could be used as a scaler for instance.
00239 */
00240 void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) {
00241     ee_u32 i,j;
00242     for (i=0; i<N; i++) {
00243         for (j=0; j<N; j++) {
00244             C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val;
00245         }
00246     }
00247 }
00248 
00249 /* Function: matrix_add_const
00250     Add a constant value to all elements of a matrix.
00251 */
00252 void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) {
00253     ee_u32 i,j;
00254     for (i=0; i<N; i++) {
00255         for (j=0; j<N; j++) {
00256             A[i*N+j] += val;
00257         }
00258     }
00259 }
00260 
00261 /* Function: matrix_mul_vect
00262     Multiply a matrix by a vector.
00263     This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
00264 */
00265 void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
00266     ee_u32 i,j;
00267     for (i=0; i<N; i++) {
00268         C[i]=0;
00269         for (j=0; j<N; j++) {
00270             C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j];
00271         }
00272     }
00273 }
00274 
00275 /* Function: matrix_mul_matrix
00276     Multiply a matrix by a matrix.
00277     Basic code is used in many algorithms, mostly with minor changes such as scaling.
00278 */
00279 void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
00280     ee_u32 i,j,k;
00281     for (i=0; i<N; i++) {
00282         for (j=0; j<N; j++) {
00283             C[i*N+j]=0;
00284             for(k=0;k<N;k++)
00285             {
00286                 C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
00287             }
00288         }
00289     }
00290 }
00291 
00292 /* Function: matrix_mul_matrix_bitextract
00293     Multiply a matrix by a matrix, and extract some bits from the result.
00294     Basic code is used in many algorithms, mostly with minor changes such as scaling.
00295 */
00296 void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
00297     ee_u32 i,j,k;
00298     for (i=0; i<N; i++) {
00299         for (j=0; j<N; j++) {
00300             C[i*N+j]=0;
00301             for(k=0;k<N;k++)
00302             {
00303                 MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
00304                 C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7);
00305             }
00306         }
00307     }
00308 }