Benchmark: DAC versus Sigma-Delta

JoaoLopesF
Posts: 59
Joined: Thu Aug 17, 2017 5:40 pm

Benchmark: DAC versus Sigma-Delta

Postby JoaoLopesF » Sun Jun 10, 2018 4:45 pm

Hi,

I did a benchmark of DAC x Sigma-Delta:

Code: Select all

/*
 * main.c
 *
 *  Created on: 9 de jun de 2018
 *      Author: Joao Lopes
 */

#include <stdio.h>
#include <stddef.h>
#include "esp_types.h"
#include "esp_system.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_timer.h"
#include <driver/dac.h>
#include "driver/gpio.h"
#include "driver/sigmadelta.h"

static const char *tag = "Benchmark";

void app_main()
{
	ESP_LOGI (tag, "Main - Begin");

	// Initialize DAC

	dac_output_enable(DAC_CHANNEL_1);

	// Initialize Sigma Delta

    sigmadelta_config_t sigmadelta_cfg = {
        .channel = SIGMADELTA_CHANNEL_0,
        .sigmadelta_prescale = 80,
        .sigmadelta_duty = 0,
        .sigmadelta_gpio = 4,
    };
    sigmadelta_config(&sigmadelta_cfg);

    // Variables

	uint16_t times = 100;
	uint64_t timeBegin;
	float avg;

	// Dac

	timeBegin = esp_timer_get_time();

	for (uint16_t i = 0; i<times; i++) {
		dac_output_voltage(DAC_CHANNEL_1, 100);
	}

	uint32_t totalTimeDac = (esp_timer_get_time() - timeBegin);

	avg = ((float) totalTimeDac / (float) times);

	ESP_LOGI(tag, "*** DAC Time total %u avg %f", totalTimeDac, avg);

	// SigmaDelta

	timeBegin = esp_timer_get_time();

	for (uint16_t i = 0; i<times; i++) {
        sigmadelta_set_duty(SIGMADELTA_CHANNEL_0, 100);
	}

	uint32_t totalTimeSigmaDelta = (esp_timer_get_time() - timeBegin);

	avg = ((float) totalTimeSigmaDelta / (float) times);

	ESP_LOGI(tag, "*** SigmaDelta Time total %u avg %f", totalTimeSigmaDelta, avg);

	ESP_LOGI(tag, "*** Factor Dac/SigmaDelta %.2f %%", (totalTimeDac / totalTimeSigmaDelta) * 100.0f);

	ESP_LOGI (tag, "Main - End");

}

Code: Select all

Output on Monitor (@ 160MHz):

I (169)P(01) Benchmark: Main - Begin
I (169)P(00) Benchmark: *** DAC Time total 454 avg 4.540000
I (169)P(00) Benchmark: *** SigmaDelta Time total 32 avg 0.320000
I (169)P(00) Benchmark: *** Factor Dac/SigmaDelta 1400.00 %
I (179)P(10) Benchmark: Main - End

Sigma-Delta have a very good time (0.32 us) :-)

Why DAC is 1400% more slow than Sigma-Delta ?

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Benchmark: DAC versus Sigma-Delta

Postby ESP_Sprite » Mon Jun 11, 2018 2:09 am

Because at least that DAC output routine is not optimized for speed. For most people who want to get speed out of the DAC, they're better off connecting it to the I2S peripheral and feeding it that way. You can get multiple MHzs of speed that way without any CPU interference.

JoaoLopesF
Posts: 59
Joined: Thu Aug 17, 2017 5:40 pm

Re: Benchmark: DAC versus Sigma-Delta

Postby JoaoLopesF » Mon Jun 11, 2018 10:33 pm

Hi, ESP_Sprite

Thanks for you response.

I modified the program to do benchmark in core 1 too:

Code: Select all

/*
 * main.c
 *
 *  Created on: 9 de jun de 2018
 *      Author: Joao Lopes
 */

#include <stdio.h>
#include <stddef.h>
#include "esp_types.h"
#include "esp_system.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_timer.h"
#include <driver/dac.h>
#include "driver/gpio.h"
#include "driver/sigmadelta.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

// Variables

static const char *tag = "Benchmark";

const uint16_t timesBenchmark = 1u;
const uint16_t timesOutput = 1000u;
uint32_t totalTimeDac[2] = {0, 0};
uint32_t totalTimeSigmaDelta[2] = {0, 0};

// Benchmark

void benchmark() {

    // Variables

	uint64_t timeBegin = 0u;
	float avg = 0.0f;

	// Benchmark

    ESP_LOGI(tag, "***  Benchmark DAC/SigmaDelta - on core %d", xPortGetCoreID());

    for (uint8_t i=1; i<=timesBenchmark; i++) {

    	ESP_LOGI(tag, "*** Benchmark: %d", i);

    	// Dac

    	timeBegin = esp_timer_get_time();

    	for (uint16_t i = 0; i<timesOutput; i++) {
    		dac_output_voltage(DAC_CHANNEL_1, 100u);
    	}

    	uint32_t timeDac = (esp_timer_get_time() - timeBegin);
    	totalTimeDac[xPortGetCoreID()] += timeDac;

    	avg = ((float) timeDac / (float) timesOutput);

    	ESP_LOGI(tag, "*** DAC        Time total %u avg %.3f", timeDac, avg);

    	// SigmaDelta

    	timeBegin = esp_timer_get_time();

    	for (uint16_t i = 0; i<timesOutput; i++) {
            sigmadelta_set_duty(SIGMADELTA_CHANNEL_0, 100u);
    	}

    	uint32_t timeSigmaDelta = (esp_timer_get_time() - timeBegin);
    	totalTimeSigmaDelta[xPortGetCoreID()] += timeSigmaDelta;

    	avg = ((float) timeSigmaDelta / (float) timesOutput);

    	ESP_LOGI(tag, "*** SigmaDelta Time total %u avg %.3f", timeSigmaDelta, avg);

    	ESP_LOGI(tag, "*** Factor Dac/SigmaDelta %.2f %%", (timeDac / timeSigmaDelta) * 100.0f);

    }

}

// Averages for CPU

void averagesCPU() {

	ESP_LOGW(tag, "*** Average for Core ***");

	float avg = 0.0f;

	for (uint8_t c=0; c<=1; c++) {

		ESP_LOGW(tag, "*** Core %d", c);

		avg = ((float) totalTimeDac[c] / (float) timesOutput / (float) timesBenchmark);

		ESP_LOGI(tag, "*** DAC        avg %.3f", avg);

		avg = ((float) totalTimeSigmaDelta[c] / (float) timesOutput / (float) timesBenchmark);

		ESP_LOGI(tag, "*** SigmaDelta avg %.3f", avg);

		ESP_LOGI(tag, "*** Factor Dac/SigmaDelta %.2f %%", (totalTimeDac[c] / totalTimeSigmaDelta[c]) * 100.0f);
	}

	ESP_LOGW(tag, "********");

}
static void benchmarkCPU1_task(void *arg) {

	// Task on CPU 1 to rum the benchmark

	benchmark();

	// Averages for CPU

	averagesCPU();

	// Delete this task

	vTaskDelete(NULL);

}

	// Task das atividades dos leds
void app_main()
{
	ESP_LOGI (tag, "Main - Begin");

	// Initialize DAC

	dac_output_enable(DAC_CHANNEL_1);

	// Initialize Sigma Delta

    sigmadelta_config_t sigmadelta_cfg = {
        .channel = SIGMADELTA_CHANNEL_0,
        .sigmadelta_prescale = 80,
        .sigmadelta_duty = 0,
        .sigmadelta_gpio = 4,
    };
    sigmadelta_config(&sigmadelta_cfg);

    // Benchmark on CPU 0

    benchmark();

    // Benchmark on CPU 1

	xTaskCreatePinnedToCore(&benchmarkCPU1_task, "bench_task", 5120, NULL, 15, NULL, APP_CPU_NUM);


	// End

	ESP_LOGI (tag, "Main - End");

}

Code: Select all

Monitor output (Esp32 @160MHz):

I (169)P(01) Benchmark: Main - Begin
I (169)P(00) Benchmark: ***  Benchmark DAC/SigmaDelta - on core 0
I (169)P(00) Benchmark: *** Benchmark: 1
I (179)P(10) Benchmark: *** DAC        Time total 4334 avg 4.334
I (179)P(00) Benchmark: *** SigmaDelta Time total 280 avg 0.280
I (179)P(00) Benchmark: *** Factor Dac/SigmaDelta 1500.00 %
I (179)P(00) Benchmark: Main - End
I (179)P(00) Benchmark: ***  Benchmark DAC/SigmaDelta - on core 1
I (189)P(10) Benchmark: *** Benchmark: 1
I (189)P(00) Benchmark: *** DAC        Time total 4313 avg 4.313
I (189)P(00) Benchmark: *** SigmaDelta Time total 296 avg 0.296
I (189)P(00) Benchmark: *** Factor Dac/SigmaDelta 1400.00 %
W (199)P(10) Benchmark: *** Average for Core ***
W (199)P(00) Benchmark: *** Core 0
I (199)P(00) Benchmark: *** DAC        avg 4.334
I (199)P(00) Benchmark: *** SigmaDelta avg 0.280
I (209)P(10) Benchmark: *** Factor Dac/SigmaDelta 1500.00 %
W (209)P(00) Benchmark: *** Core 1
I (209)P(00) Benchmark: *** DAC        avg 4.313
I (209)P(00) Benchmark: *** SigmaDelta avg 0.296
I (219)P(10) Benchmark: *** Factor Dac/SigmaDelta 1400.00 %
W (219)P(00) Benchmark: ********
Interesting that in cpu 1, DAC got a little bit faster and Sigma-Delta a little slower, why will it?

Who is online

Users browsing this forum: No registered users and 100 guests