[Sound-open-firmware] [PATCH v2] [RFC]platform: calculate the percentage of cpu cycle

zhigangw zhigang.wu at linux.intel.com
Wed Jun 27 03:34:37 CEST 2018



On 2018年06月26日 23:39, Pierre-Louis Bossart wrote:
> On 6/26/18 2:23 AM, Wu Zhigang wrote:
>> calculate the percentage of cpu cyle based on
>> the CCOUNT register. which can tell the percentage
>> of cpu cycle usage. It is the rough calculation.
>
> Sorry, this makes no sense to me.
> First there can be more than one DMA channel active, so doing the 
> calculation could be done multiple times. Not to mention that if we 
> provide a CPU load estimate it should be available for capture as well 
> as playback.
> And then why should we make the assumption that a DMA completes every 
> ms? When the DMA will be setup to deal with smaller periods to 
> low-latency usages the 1ms value will not cut it.
>
Yes, your concern is correct. I also conceived this shortcoming before.
Actually the best way is to enable a timer (1ms a interrupt) to read the 
accumulator and calculate the percentage.
Not sure which timer is ok for this. the DSP can squeeze out this 
resource for this job? Maybe we have other targets for these timers.
My concern is the CCOUNT register read location is proper?
If this is the right location to do this.
I can refine it with timer to do this job.
Thanks
~Zhigang
>>
>> Signed-off-by: Wu Zhigang <zhigang.wu at linux.intel.com>
>> ---
>>   src/audio/dai.c        | 22 ++++++++++++++++++++++
>>   src/include/sof/wait.h |  8 ++++++++
>>   src/tasks/audio.c      | 10 ++++++++++
>>   3 files changed, 40 insertions(+)
>>
>> diff --git a/src/audio/dai.c b/src/audio/dai.c
>> index f6f16d7..11b20c5 100644
>> --- a/src/audio/dai.c
>> +++ b/src/audio/dai.c
>> @@ -43,11 +43,14 @@
>>   #include <sof/audio/component.h>
>>   #include <sof/audio/pipeline.h>
>>   #include <platform/dma.h>
>> +#include <platform/clk.h>
>>   #include <arch/cache.h>
>>     #define DAI_PLAYBACK_STREAM    0
>>   #define DAI_CAPTURE_STREAM    1
>>   +#define CPU_CYCLE_PER_MS    (CLK_DEFAULT_CPU_HZ / 1000)
>> +
>>   /* tracing */
>>   #define trace_dai(__e) trace_event(TRACE_CLASS_DAI, __e)
>>   #define trace_dai_error(__e)   trace_error(TRACE_CLASS_DAI, __e)
>> @@ -72,6 +75,22 @@ struct dai_data {
>>       uint64_t wallclock;    /* wall clock at stream start */
>>   };
>>   +static void calc_cpu_usage(struct pipeline *p)
>> +{
>> +    uint32_t delta = 0;
>> +
>> +    delta = global_cycle;
>> +    global_cycle = 0;
>> +    if (delta > CPU_CYCLE_PER_MS)
>> +        delta = CPU_CYCLE_PER_MS;
>> +    delta = (delta * 100) / CPU_CYCLE_PER_MS;
>> +
>> +    trace_dai_error("PcT");
>> +
>> +    /* the percentage of the cpu usage in 1ms */
>> +    trace_error_value(100 - delta);
>> +}
>> +
>>   /* this is called by DMA driver every time descriptor has completed */
>>   static void dai_dma_cb(void *data, uint32_t type, struct 
>> dma_sg_elem *next)
>>   {
>> @@ -81,6 +100,9 @@ static void dai_dma_cb(void *data, uint32_t type, 
>> struct dma_sg_elem *next)
>>         tracev_dai("irq");
>>   +    if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK)
>> +        calc_cpu_usage(dev->pipeline);
>> +
>>       /* stop dma copy for pause/stop/xrun */
>>       if (dev->state != COMP_STATE_ACTIVE || dd->xrun) {
>>   diff --git a/src/include/sof/wait.h b/src/include/sof/wait.h
>> index feb8b29..4baa8de 100644
>> --- a/src/include/sof/wait.h
>> +++ b/src/include/sof/wait.h
>> @@ -43,6 +43,7 @@
>>   #include <sof/trace.h>
>>   #include <sof/lock.h>
>>   #include <platform/interrupt.h>
>> +#include <xtensa/hal.h>
>>     #if DEBUG_LOCKS
>>   #define wait_atomic_check    \
>> @@ -157,4 +158,11 @@ static inline void wait_delay(uint64_t 
>> number_of_clks)
>>           idelay(PLATFORM_DEFAULT_DELAY);
>>   }
>>   +uint32_t global_cycle;
>> +
>> +static inline uint32_t platform_get_cpu_count(void)
>> +{
>> +    return xthal_get_ccount();
>> +}
>> +
>>   #endif
>> diff --git a/src/tasks/audio.c b/src/tasks/audio.c
>> index 5beae08..1a79808 100644
>> --- a/src/tasks/audio.c
>> +++ b/src/tasks/audio.c
>> @@ -51,6 +51,9 @@ struct audio_data {
>>       struct pipeline *p;
>>   };
>>   +uint32_t global_cycle;
>> +static uint32_t c1, c2;
>> +
>>   int do_task(struct sof *sof)
>>   {
>>   #ifdef STATIC_PIPE
>> @@ -78,13 +81,20 @@ int do_task(struct sof *sof)
>>       /* let host know DSP boot is complete */
>>       platform_boot_complete(0);
>>   +    global_cycle = 0;
>> +
>>       /* main audio IPC processing loop */
>>       while (1) {
>>   +        c1 = platform_get_cpu_count();
>> +
>>           /* sleep until next IPC or DMA */
>>           sa_enter_idle(sof);
>>           wait_for_interrupt(0);
>>   +        c2 = platform_get_cpu_count();
>> +        global_cycle += c2 - c1;
>> +
>>           /* now process any IPC messages from host */
>>           ipc_process_msg_queue();
>>
>
> _______________________________________________
> Sound-open-firmware mailing list
> Sound-open-firmware at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware



More information about the Sound-open-firmware mailing list