demo_cache.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // See LICENSE for license details.
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "nuclei_sdk_soc.h"
  5. #include "nmsis_bench.h"
  6. #if !defined(__CCM_PRESENT) || (__CCM_PRESENT != 1)
  7. /* __CCM_PRESENT should be defined in <Device>.h */
  8. #warning "__CCM_PRESENT is not defined or equal to 1, please check!"
  9. #warning "This example requires CPU CCM feature!"
  10. #endif
  11. #if !defined(__DCACHE_PRESENT) || (__DCACHE_PRESENT != 1)
  12. /* __DCACHE_PRESENT should be defined in <Device>.h */
  13. #error "This example requires CPU DCACHE feature!"
  14. #endif
  15. // Declare HPMCOUNTER3
  16. HPM_DECLARE_VAR(3);
  17. // Declare HPMCOUNTER4
  18. HPM_DECLARE_VAR(4);
  19. // Means select the ICache miss events, record ICache miss event for all M/S/U mode
  20. #define HPM_EVENT3 HPM_EVENT(EVENT_SEL_MEMORY_ACCESS, EVENT_MEMORY_ACCESS_ICACHE_MISS, MSU_EVENT_ENABLE)
  21. // Means select the DCache miss events, record DCache miss event for all M/S/U mode
  22. #define HPM_EVENT4 HPM_EVENT(EVENT_SEL_MEMORY_ACCESS, EVENT_MEMORY_ACCESS_DCACHE_MISS, MSU_EVENT_ENABLE)
  23. //#define BIG_ROW_SIZE
  24. #ifndef BIG_ROW_SIZE
  25. #define ROW_SIZE 10
  26. #else
  27. #define ROW_SIZE 2048
  28. #endif
  29. /* Column size same as cache line size, for better understanding cache mechanism*/
  30. #define COL_SIZE 64
  31. uint8_t array_test[ROW_SIZE][COL_SIZE] __attribute__((aligned(0x40))) = {0};
  32. void array_update_by_row(void)
  33. {
  34. int32_t i, j = 0;
  35. for (i = 0; i < ROW_SIZE; i++)
  36. for (j = 0; j < COL_SIZE; j++) {
  37. array_test[i][j] = 0xab;
  38. }
  39. }
  40. void array_update_by_col(void)
  41. {
  42. int32_t i, j = 0;
  43. for (i = 0; i < COL_SIZE; i++)
  44. for (j = 0; j < ROW_SIZE; j++) {
  45. array_test[j][i] = 0xab;
  46. }
  47. }
  48. void array_init(void)
  49. {
  50. int32_t i, j = 0;
  51. for (i = 0; i < ROW_SIZE; i++)
  52. for (j = 0; j < COL_SIZE; j++) {
  53. array_test[i][j] = 0x34;
  54. }
  55. }
  56. BENCH_DECLARE_VAR();
  57. int main(void)
  58. {
  59. #if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)
  60. int32_t ret = 0;
  61. int32_t val = 0;
  62. CacheInfo_Type cacheinfo_type;
  63. BENCH_INIT();
  64. if (!DCachePresent()) {
  65. printf("DCache not present in CPU!\n");
  66. return -1;
  67. }
  68. GetDCacheInfo(&cacheinfo_type);
  69. printf("DCache Linesize is %d bytes, ways is %d, setperway is %d, total size is %d bytes\n\n", cacheinfo_type.linesize, \
  70. cacheinfo_type.ways, cacheinfo_type.setperway,cacheinfo_type.size);
  71. printf("array_test %d * %d bytes\n", ROW_SIZE, COL_SIZE);
  72. printf("\n------Update array in memory------\n");
  73. EnableDCache();
  74. MFlushDCache();
  75. MInvalDCache();
  76. MInvalICache();
  77. // Init HPM bench, only need to do it once
  78. HPM_INIT();
  79. printf("\n------Update array to all 0xab in cache: array_update_by_row------\n");
  80. // start to record hpm3 and hpm4
  81. HPM_START(3, array_update_by_row_icache_miss, HPM_EVENT3);
  82. HPM_START(4, array_update_by_row_dcache_miss, HPM_EVENT4);
  83. BENCH_START(array_update_by_row_cycle);
  84. array_update_by_row();
  85. BENCH_END(array_update_by_row_cycle);
  86. // finish record and print hpm value
  87. HPM_END(4, array_update_by_row_dcache_miss, HPM_EVENT4);
  88. HPM_END(3, array_update_by_row_icache_miss, HPM_EVENT3);
  89. printf("\n-------Keep DCache valid, do array_update_by_row again-------\n");
  90. HPM_START(3, array_update_by_row_icache_miss, HPM_EVENT3);
  91. HPM_START(4, array_update_by_row_dcache_miss, HPM_EVENT4);
  92. BENCH_START(array_update_by_row_cycle);
  93. array_update_by_row();
  94. BENCH_END(array_update_by_row_cycle);
  95. HPM_END(4, array_update_by_row_dcache_miss, HPM_EVENT4);
  96. HPM_END(3, array_update_by_row_icache_miss, HPM_EVENT3);
  97. printf("\n-------Invalidate all the Dcache-------\n");
  98. MInvalDCache();
  99. printf("\n------Update array to all 0xab in cache: array_update_by_col ------\n");
  100. HPM_START(4, array_update_by_col_dcache_miss, HPM_EVENT4);
  101. BENCH_START(array_update_by_col_cycle);
  102. array_update_by_col();
  103. BENCH_END(array_update_by_col_cycle);
  104. HPM_END(4, array_update_by_col_dcache_miss, HPM_EVENT4);
  105. printf("Read out array_test[0][0] 0x%x in cache, then disable DCache\n", array_test[0][0]);
  106. DisableDCache();
  107. printf("\n------Init array in memory to all 0x34------\n");
  108. array_init();
  109. printf("Read out array_test[0][0] 0x%x in memory, then enable Dcache\n", array_test[0][0]);
  110. EnableDCache();
  111. MFlushDCache();
  112. printf("After cache flushed to memory, array_test[0][0] in memory is 0x%x\n", array_test[0][0]);
  113. printf("\n------Again init array in memory to all 0x34, then enable DCache------\n");
  114. DisableDCache();
  115. array_init();
  116. /* Read from memory */
  117. printf("Read out array_test[0][0] 0x%x in memory\n", array_test[0][0]);
  118. EnableDCache();
  119. printf("Read out array_test[0][0] 0x%x in cache, when mapped value in memory has changed\n", array_test[0][0]);
  120. MInvalDCache();
  121. HPM_START(4, dcachemiss_readonebyte, HPM_EVENT4);
  122. /* Read brings in one cache miss */
  123. val = *(volatile uint8_t*) &array_test[0][0];
  124. HPM_END(4, dcachemiss_readonebyte, HPM_EVENT4);
  125. #else
  126. printf("[ERROR]__CCM_PRESENT must be defined as 1 in <Device>.h!\r\n");
  127. #endif
  128. return 0;
  129. }