initial commit
This commit is contained in:
14
sdk/software/examples/c_prg/loop_induction/Makefile
Normal file
14
sdk/software/examples/c_prg/loop_induction/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
TARGET = loop_induction
|
||||
|
||||
CFLAGS += -O3 -g
|
||||
|
||||
#根据SIMU宏选择串口波特率,0:FPGA上板;1:仿真
|
||||
CFLAGS += -DSIMU=0
|
||||
|
||||
C_SRCS := $(wildcard ./*.c )
|
||||
|
||||
OBJDIR = obj
|
||||
COMMON_DIR = ../../../bsp
|
||||
GCC_DIR=../../../../toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0
|
||||
PICOLIBC_DIR=../../../../toolchains/picolibc
|
||||
include ../../../bsp/common.mk
|
||||
131
sdk/software/examples/c_prg/loop_induction/loop_induction.c
Normal file
131
sdk/software/examples/c_prg/loop_induction/loop_induction.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright 2018 Chris Cox
|
||||
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
|
||||
or a copy at http://stlab.adobe.com/licenses.html )
|
||||
|
||||
|
||||
Goal: Examine performance optimizations related to loop induction variables.
|
||||
|
||||
|
||||
Assumptions:
|
||||
1) The compiler will normalize all loop types and optimize all equally.
|
||||
(this is a necessary step before doing induction variable analysis)
|
||||
|
||||
2) The compiler will remove unused induction variables.
|
||||
This could happen due to several optimizations.
|
||||
|
||||
2) The compiler will recognize induction variables with linear relations (x = a*b + c)
|
||||
and optimize out redundant variables.
|
||||
|
||||
3) The compiler will apply strength reduction to induction variable usage.
|
||||
|
||||
4) The compiler will remove bounds checks by recognizing or adjusting loop limits.
|
||||
(can be an explict loop optimization, or part of range propagation)
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
//BSP板级支持包所需全局变量
|
||||
unsigned long UART_BASE = 0xbfe001e0; //UART16550的虚地址
|
||||
unsigned long CONFREG_UART_BASE = 0xbfafff10; //CONFREG模拟UART的虚地址
|
||||
unsigned long CONFREG_TIMER_BASE = 0xbfafe000; //CONFREG计数器的虚地址
|
||||
unsigned long CONFREG_CLOCKS_PER_SEC = 100000000L; //CONFREG时钟频率
|
||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L; //处理器核时钟频率
|
||||
|
||||
clock_t start_time, end_time;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// this constant may need to be adjusted to give reasonable minimum times
|
||||
// For best results, times should be about 1.0 seconds for the minimum test run
|
||||
int iterations = 10;
|
||||
|
||||
|
||||
// 32000 items, or about 128k of data
|
||||
// this is intended to remain within the L2 cache of most common CPUs
|
||||
const int SIZE = 32000;
|
||||
|
||||
|
||||
// initial value for filling our arrays, may be changed from the command line
|
||||
int init_value = 3;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void fill_random(int32_t * first, int32_t * last) {
|
||||
while (first != last) {
|
||||
*first++ = (int32_t)rand();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
void test_copy(const int32_t *source, int32_t *dest, int count, const char *label) {
|
||||
int i;
|
||||
|
||||
fill_random( dest, dest+count );
|
||||
|
||||
start_time = clock();
|
||||
|
||||
for(i = 0; i < iterations; ++i) {
|
||||
int i, j, k;
|
||||
for ( i=0, j=0, k=0; k < count; ++i, ++j, ++k ) {
|
||||
dest[i] = source[j];
|
||||
}
|
||||
}
|
||||
|
||||
end_time = clock();
|
||||
|
||||
if ( memcmp(dest, source, count*sizeof(int32_t)) != 0 )
|
||||
printf("test %s failed\n", label);
|
||||
|
||||
double time_cost = (end_time - start_time)/ (double)(CLOCKS_PER_SEC);
|
||||
|
||||
printf("\"%s, %d items\" %f sec\n",
|
||||
label,
|
||||
count,
|
||||
time_cost);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// output command for documentation:
|
||||
int i;
|
||||
// for (i = 0; i < argc; ++i)
|
||||
// printf("%s ", argv[i] );
|
||||
// printf("\n");
|
||||
|
||||
if (argc > 1) iterations = atoi(argv[1]);
|
||||
if (argc > 2) init_value = (int) atoi(argv[2]);
|
||||
|
||||
int32_t intSrc[ SIZE ];
|
||||
int32_t intDst[ SIZE ];
|
||||
|
||||
|
||||
srand( (unsigned int)init_value + 123);
|
||||
fill_random( intSrc, intSrc+SIZE );
|
||||
|
||||
|
||||
test_copy( &intSrc[0], &intDst[0], SIZE, "int32_t for induction copy" );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the end
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
Reference in New Issue
Block a user