PASDK-258:Add LibArch release from Jianzhong
[processor-sdk/performance-audio-sr.git] / psdk_cust / libarch_k2g_1_0_1_0 / examples / common / test_dsp_edma_bench.c
1 /******************************************************************************
2  * Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com
3  *   All rights reserved.
4  *
5  *   Redistribution and use in source and binary forms, with or without
6  *   modification, are permitted provided that the following conditions are met:
7  *       * Redistributions of source code must retain the above copyright
8  *         notice, this list of conditions and the following disclaimer.
9  *       * Redistributions in binary form must reproduce the above copyright
10  *         notice, this list of conditions and the following disclaimer in the
11  *         documentation and/or other materials provided with the distribution.
12  *       * Neither the name of Texas Instruments Incorporated nor the
13  *         names of its contributors may be used to endorse or promote products
14  *         derived from this software without specific prior written permission.
15  *
16  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  *   THE POSSIBILITY OF SUCH DAMAGE.
27  *****************************************************************************/
28 /*==============================================================================
29   This file shows an example of using LibArch function to do memory copy.
30 ===============================================================================*/ 
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
35 #include <xdc/std.h>
36 #include <ti/csl/csl_tsc.h>
37 #include <ti/sdo/edma3/drv/edma3_drv.h>
38 #include <ti/sdo/edma3/drv/sample/bios6_edma3_drv_sample.h>
39 #include <ti/libarch/libarch.h>
40 #include <ti/sysbios/hal/Cache.h>
42 #define TEST_BUFF_SIZE (1024*1024)
43 #define TEST_DATA_SIZE (1024*1024)
44 #define MAX_EDMA_1D1D_COPY_SIZE  (65535)
45 #define EDMA_2D2D_COPY_LINE_SIZE (1024)
47 #pragma DATA_SECTION(data_buf1, ".DDR_DATA")
48 #pragma DATA_ALIGN(data_buf1,128)
49 char data_buf1[TEST_BUFF_SIZE];
51 #pragma DATA_SECTION(data_buf2, ".DDR_DATA")
52 #pragma DATA_ALIGN(data_buf2,128)
53 char data_buf2[TEST_BUFF_SIZE];
55 extern signed char*  getGlobalAddr(signed char* addr);
57 void fill_buffers(int *buf1, int *buf2, int num_elements);
58 int verify_copy(char *in_ptr, char *out_ptr, int num_bytes);
61 /*==============================================================================
62  * This function benchmarks data transfer in external memory. It measures clock
63  * cycles taken by memcpy versus LibArch functions for transfer sizes from
64  * 8 bytes to 1M bytes.
65  *============================================================================*/
66 void lib_benchmark_data_transfer()
67 {
68     EDMA3_DRV_Result result;
69     Uint32 num_bytes, num_bytes_per_line, num_lines, pitch, test_data_size;
70     lib_emt_Handle handle_emt;
71     uint64_t clock_cntr_start, clock_cntr_end, cycles_edma, cycles_memcpy;
72     int *in_ptr, *out_ptr;
73     
74     /* allocate a LibArch channel for data transfer */
75     handle_emt = lib_emt_alloc(1);  // 1 as a dummy number as linked transfer is not used
76     
77     printf("Benchmarking results:\n");
78     printf("Transfer size (bytes)\t LibArch API\t memcpy\n");
80     in_ptr    = (int *)getGlobalAddr((signed char *)&data_buf1[0]);   // necessary when data_buf in L2 SRAM
81     out_ptr   = (int *)getGlobalAddr((signed char *)&data_buf2[0]);
82     
83     lib_clock_enable();
85     for(test_data_size=8; test_data_size<=TEST_BUFF_SIZE; test_data_size*=2)
86     {
87         /* Fill buffers with data for testing. */
88         fill_buffers((int *)&data_buf1[0], (int *)&data_buf2[0], test_data_size/sizeof(int));
90         num_bytes = test_data_size;
91         
92         /* Necessary to flush/invalidate cache when buffers are in cacheable area */
93         Cache_wb(in_ptr, num_bytes, Cache_Type_ALL, (Bool)TRUE);
94         Cache_inv(out_ptr, num_bytes, Cache_Type_ALL, (Bool)TRUE);
95         
96         /*----- measure clock cycles used by LibArch functions -----*/
97         if(num_bytes <= MAX_EDMA_1D1D_COPY_SIZE) {
98             /* 1D1D copy for sizes smaller than 65535 */
99             clock_cntr_start = lib_clock_read();
100         
101             lib_emt_copy1D1D(handle_emt, in_ptr, out_ptr, num_bytes);
102         
103             lib_emt_wait(handle_emt);
104         
105             clock_cntr_end = lib_clock_read();
106         
107             cycles_edma = clock_cntr_end - clock_cntr_start;
108         
109             if(verify_copy((char *)in_ptr, (char *)out_ptr, num_bytes)) {
110                 //printf("Clock cycles used by EDMA 1D1D copy is %lld.\n", cycles_edma);
111             } 
112             else {
113                 printf("1D1D copy error!\n");
114             }      
115         } /* 1D1D copy */
116         else {    
117             /* 2D2D copy for sizes larger than 65535 */
118             clock_cntr_start = lib_clock_read();
119         
120             num_bytes_per_line = EDMA_2D2D_COPY_LINE_SIZE;
121             num_lines = num_bytes / EDMA_2D2D_COPY_LINE_SIZE;
122             pitch = EDMA_2D2D_COPY_LINE_SIZE;
123             lib_emt_copy2D2D(handle_emt, in_ptr, out_ptr, num_bytes_per_line, num_lines, pitch, pitch);
124         
125             lib_emt_wait(handle_emt);
126         
127             clock_cntr_end   = lib_clock_read();
128         
129             cycles_edma = clock_cntr_end - clock_cntr_start;
130         
131             if(verify_copy((char *)in_ptr, (char *)out_ptr, num_bytes)) {
132                 //printf("Clock cycles used by EDMA 2D2D copy is %lld.\n", cycles_edma);
133             } 
134             else {
135                 printf("2D2D copy error!\n");
136             }    
137         }  /* 2D2D copy */
139         /* Refill buffers with data for testing. */
140         fill_buffers((int *)&data_buf1[0], (int *)&data_buf2[0], test_data_size/sizeof(int));
141         
142         /*----- measure clock cycles used by memcpy  -----*/
143         clock_cntr_start = lib_clock_read();
145         memcpy(&data_buf2[0], &data_buf1[0], num_bytes);
147         clock_cntr_end   = lib_clock_read();
148         cycles_memcpy    = clock_cntr_end - clock_cntr_start;
150         if(verify_copy((char *)&data_buf1[0], (char *)&data_buf2[0], num_bytes)) {
151             //printf("Clock cycles used by memcpy is %lld.\n", cycles_memcpy);
152         }
153         else {
154             printf("memcpy error!\n");
155         }
157         printf("%d\t\t\t%lld\t\t%lld\n", num_bytes, cycles_memcpy, cycles_edma);
158     }
160     /* free the LibArch channel allocated earlier */
161     lib_emt_free(handle_emt);
162 } /* lib_benchmark_data_transfer */
165 /*==============================================================================
166  * This function fills buffers with data. 
167  *============================================================================*/
168 void fill_buffers(int *buf1, int *buf2, int num_elements)
170     int i;
172     for(i=0; i<num_elements; i++)
173     {
174         buf1[i] = i;
175         buf2[i] = i*2;
176     }
177 } /* fill_buffers */
179 /*==============================================================================
180  * This function compares the source (in) and destination (out) buffers to verify
181  * the correctness of the data copy. 
182  *============================================================================*/
183 int verify_copy(char *in_ptr, char *out_ptr, int num_bytes)
185     int i, num_diff;
186     
187     num_diff = 0;
188     for(i=0; i<num_bytes; i++)
189     {
190         if(in_ptr[i] != out_ptr[i]) {
191             num_diff += 1;
192         }
193     }
194     
195     if(num_diff > 0) {
196         return 0;
197     }
198     else {
199         return 1;
200     }
203 /* nothing past this line */