[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;
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
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]);
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;
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);
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();
101 lib_emt_copy1D1D(handle_emt, in_ptr, out_ptr, num_bytes);
103 lib_emt_wait(handle_emt);
105 clock_cntr_end = lib_clock_read();
107 cycles_edma = clock_cntr_end - clock_cntr_start;
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();
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);
125 lib_emt_wait(handle_emt);
127 clock_cntr_end = lib_clock_read();
129 cycles_edma = clock_cntr_end - clock_cntr_start;
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));
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)
169 {
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)
184 {
185 int i, num_diff;
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 }
195 if(num_diff > 0) {
196 return 0;
197 }
198 else {
199 return 1;
200 }
201 }
203 /* nothing past this line */