f9-kernel icon indicating copy to clipboard operation
f9-kernel copied to clipboard

Implement Thumb-2 optimized memcpy/memset

Open jserv opened this issue 11 years ago • 10 comments

Directory kernel/lib contains the implementation of memcpy and memset, but it is too generic. We can utilize several ARM Cortex-M3/M4 specific features to optimize:

  • Thumb-2
    • apply 32-bit aligned data copy in inner loop, which is not necessary to Cortex-M3/M4, but it could be better for the external memory access depending on memory controller.
  • unaligned memory access
  • PLD instruction to preload cache with memory source

jserv avatar Feb 06 '14 20:02 jserv

Reference:

  • http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56620
  • https://sourceware.org/ml/newlib/2013/msg00419.html
  • http://www.keil.com/forum/22856/
  • http://cboard.cprogramming.com/c-programming/154333-fast-memcpy-alternative-32-bit-embedded-processor-posted-just-fyi-fwiw.html

jserv avatar Feb 06 '14 21:02 jserv

lk implements arm-m optimized memcpy and memset routines in git commit https://github.com/travisg/lk/commit/33b94d9b97ef835d68aca2e5edb54f7267c70625

jserv avatar Mar 13 '14 20:03 jserv

@jserv The profile result:

  1. unalignment unalignment
  2. alignment alignment

gapry avatar Jul 29 '14 03:07 gapry

It looks so weird. Can you explain?

jserv avatar Jul 29 '14 03:07 jserv

@jserv The implementation is the branch. https://github.com/gapry/f9-kernel/blob/benchmark_memcpy/benchmark/benchmark.c

My approach is that measure the case, alignment and unalignment, five times and take the avg time. Assume my approach is correct, the data imply the conclusion is the unalignment case is better than alignment after the optimized on the stm32F407.

gapry avatar Jul 29 '14 04:07 gapry

@gapry In order to clarify the performance gain, please compare the optimized memcpy routines with plain byte-oriented C version.

jserv avatar Jul 29 '14 04:07 jserv

@jserv What does plain byte-oriented mean ?

gapry avatar Jul 29 '14 04:07 gapry

The simplest and inefficient implementation of memcpy:

void memcpy(void* src, void* dst, size_t len)
{
    char* p = (char*)src;
    char* q = (char*)dst;
    while(len--) *p++ = *q++;
}

jserv avatar Jul 29 '14 04:07 jserv

@jserv For now, I use DWT to measure the elapsed clock cycles. You can check the commit: https://github.com/gapry/f9-kernel/commit/33e58dfcb1105140365132269c596763531e9ede

and the completed Implementation: https://github.com/gapry/f9-kernel/blob/benchmark_memcpy/benchmark/benchmark.c

The profile result: unalignment: dwt_unalign

alignment: dwt_align

gapry avatar Jul 29 '14 10:07 gapry

@gapry I don't think your benchmarking is valid since it doesn't represent the variance. There must be something wrong.

jserv avatar Jul 29 '14 12:07 jserv