Author Topic: EEVblog #240 - Power Supply Design Part 8  (Read 55054 times)

0 Members and 2 Guests are viewing this topic.

Offline ndictuTopic starter

  • Regular Contributor
  • *
  • Posts: 211
  • Country: sk
EEVblog #240 - Power Supply Design Part 8
« on: January 29, 2012, 02:21:08 pm »
Interesting episode, two things:

The DAC datasheet says it has resolution of 12bits, with max/min error of +-12bits. So that basically means it can output whatever value it wants, and stay in spec. What am I missing here?

Second thing - the code is probably in very early stage right now etc, but really? Copy pasting the output of data bits to the DAC instead of a for loop? :)
 

Offline ecat

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: gb
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #1 on: January 29, 2012, 02:45:58 pm »
Another great episode, many thanks Dave.

It may not be important but the video shows you missing one more SPI_CLK typo, see @11:12 and later near the video end. The first line of a function is always the trickiest, and the last line, that's the trickiest too. Come to think of it... Anyway...

digitalWrite( SPI_CLK, LOW)

I guess this should be SPI_SCLK, as it is your DAC is missing 1/2 of the first clock cycle ?

 

Offline chrome

  • Regular Contributor
  • *
  • Posts: 185
  • Country: be
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #2 on: January 29, 2012, 02:46:46 pm »
I think the 12LSb means if you output "100" it can be from 88->112

Also I agree on the for loop, that's just bad practice.
 

Offline tinhead

  • Super Contributor
  • ***
  • Posts: 1918
  • Country: 00
    • If you like my hacks, send me a donation
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #3 on: January 29, 2012, 03:01:33 pm »
Second thing - the code is probably in very early stage right now etc, but really? Copy pasting the output of data bits to the DAC instead of a for loop? :)

for bit banging loops are timing killer, such spaghetti code is easier to debug.
I don't want to be human! I want to see gamma rays, I want to hear X-rays, and I want to smell dark matter ...
I want to reach out with something other than these prehensile paws and feel the solar wind of a supernova flowing over me.
 

Online ejeffrey

  • Super Contributor
  • ***
  • Posts: 3922
  • Country: us
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #4 on: January 29, 2012, 03:02:45 pm »
The integral non-linearity is 12 LSBs. This means not the 12 least significant bits, but a voltage equal to 12 times the least significant bit.  This is still pretty terrible compared to more intrinsically linear DAC archetectures, but the typical value is only 2 LSB, and even 12 LSBs is only +/- 0.2% of full scale.  INL would be a bigger concern for AC applications where it leads to harmonic generation and inter-modulation distortion -- for a DC application like this it is "only" a concern for the overall accuracy, and if you were really concerned you could calibrate it out.
 

Offline thilo

  • Regular Contributor
  • *
  • Posts: 51
AW: Re: EEVblog #240 - Power Supply Design Part 8
« Reply #5 on: January 29, 2012, 03:19:31 pm »
Second thing - the code is probably in very early stage right now etc, but really? Copy pasting the output of data bits to the DAC instead of a for loop? :)

for bit banging loops are timing killer, such spaghetti code is easier to debug.
That would contradict the definition of spaghetti code.
 

Offline tinhead

  • Super Contributor
  • ***
  • Posts: 1918
  • Country: 00
    • If you like my hacks, send me a donation
Re: AW: Re: EEVblog #240 - Power Supply Design Part 8
« Reply #6 on: January 29, 2012, 03:26:53 pm »
Second thing - the code is probably in very early stage right now etc, but really? Copy pasting the output of data bits to the DAC instead of a for loop? :)

for bit banging loops are timing killer, such spaghetti code is easier to debug.
That would contradict the definition of spaghetti code.

no, you just misunderstood me. With "such" i refer to Daves code and not to loop.
I don't want to be human! I want to see gamma rays, I want to hear X-rays, and I want to smell dark matter ...
I want to reach out with something other than these prehensile paws and feel the solar wind of a supernova flowing over me.
 

Offline ndictuTopic starter

  • Regular Contributor
  • *
  • Posts: 211
  • Country: sk
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #7 on: January 29, 2012, 04:15:04 pm »
The integral non-linearity is 12 LSBs. This means not the 12 least significant bits, but a voltage equal to 12 times the least significant bit. 
Oh, that makes much more sense. Thanks :)

for bit banging loops are timing killer, such spaghetti code is easier to debug.
I don't think so. The loop is just an increment and a simple comparison with a jump. That should be two instructions on pretty much every architecture, and that will be small compared to the contents of the loop. Also, I would say this makes debugging actively harder, because it's easy to make a change and miss some block while replicating it, or something like that.
 

Offline baljemmett

  • Supporter
  • ****
  • Posts: 665
  • Country: gb
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #8 on: January 29, 2012, 04:31:30 pm »
for bit banging loops are timing killer, such spaghetti code is easier to debug.
I don't think so. The loop is just an increment and a simple comparison with a jump. That should be two instructions on pretty much every architecture, and that will be small compared to the contents of the loop.

Any halfway-decent compiler should be thinking about unrolling that sort of loop anyway as an optimisation, if it decides it has the code space to do so and the compilation settings allow such optimisations...  (NB: I haven't yet seen the latest video but from the comments I guess this is a reasonably small loop to shift bits out on a serial bus!)
 

Offline ndictuTopic starter

  • Regular Contributor
  • *
  • Posts: 211
  • Country: sk
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #9 on: January 29, 2012, 04:44:17 pm »
Any halfway-decent compiler should be thinking about unrolling that sort of loop anyway as an optimisation, if it decides it has the code space to do so and the compilation settings allow such optimisations...  (NB: I haven't yet seen the latest video but from the comments I guess this is a reasonably small loop to shift bits out on a serial bus!)
Of course, but this depends on many many variables. But even if it doesn't unroll it shouldn't hurt.

And yes, it's 8x data shift+mask, write to output and toggle clock. Wouldn't surprise me if it unrolled.
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #10 on: January 29, 2012, 04:47:36 pm »
Any halfway-decent compiler should be thinking about unrolling that sort of loop anyway as an optimisation, if it decides it has the code space to do so and the compilation settings allow such optimisations...

Typically one optimizes for space on such small micro controllers. However, since there is an AVR GCC behind it, you have more than enough flags to fiddle with to change optimization.
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline ecat

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: gb
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #11 on: January 29, 2012, 05:20:05 pm »
For loops are an essential tool in a programmers kitbag but they are not a panacea. In something that could be a time critical I/O routine they should be viewed in a critical light, or at the very least understood in relation to the compiler and underlying architecture.

Simple example:

Code: [Select]
    for( i = 0; i < 8; ++i )
         output( i );

The compiler will generate something similar to the following pseudo code...

Code: [Select]
    i = 0;
for_begin:
    if( !( i < 8) )
        goto for_exit;
    output( i );
    ++i
    goto for_begin;
for_end:

Let's assume output() is defined as a macro which executes in a single instruction cycle typical of a micro controllers I/O instructions.

if( !( i < 8 ) )
a1) If i is declared as a register variable or the compiler decides to make i a register variable then this comparison will probably execute in a single instruction cycle.
a2) If i is declared as volatile or the compiler decides not to make i a register variable then this comparison will probably execute in 2 instruction cycles plus one data fetch cycle.

Our single cycle output instruction is now taking two, three or more cycles to complete. Further, if the programmer is not careful the actual time is dependent upon the whims of the compiler writer and a combination of, often obscure, optimisation settings.

output( i );
One instruction cycle.

++i
c1) If i is declared as a register variable or the compiler decides to make i a register variable then this increment will probably execute in a single instruction cycle.
c2) If i is declared as volatile or the compiler decides not to make i a register variable then this increment will probably execute in 1 instruction cycle plus one data fetch cycle plus one data write cycle.

Our single cycle output instruction is now taking another additional instruction cycle plus possibly 2 memory access delays.

goto for_begin;
d1) If you have a working branch predictor then this may take one or two cycles. If you have a pre-fetch buffer or cache then the jump may or may not require a new set of fetch cycles.
d2) Without hardware assist as in d1) and depending on the underlying architecture a jump may require, say, 10 instruction cycles to execute.

Our single cycle output instruction is now taking another additional two to ten instruction cycles plus possibly n memory access delays.

The important things to understand are:
A simple for loop may be 5 or 10 times slower than the equivalent linear code. Indeed a standard compiler optimisation is to un-roll the loop to produce linear code... which in itself may make things better or worse.

Changing the variable qualifier, register/volatile, or having the compiler change it for you on the fly can have a significant impact on time critical code. 

It is unwise to make a blanket call without considering the underlying cpu architecture + cache + predicters.

Compilers + optimisation can and will screw you over in some of the most inventive and unforeseen ways imaginable.

If you are at all in doubt: KISS. You can usually find at least some time to optimise and beautify code once it's working, bosses love working code.
« Last Edit: January 29, 2012, 05:23:43 pm by ecat »
 

Offline ndictuTopic starter

  • Regular Contributor
  • *
  • Posts: 211
  • Country: sk
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #12 on: January 29, 2012, 06:28:08 pm »
The important things to understand are:
A simple for loop may be 5 or 10 times slower than the equivalent linear code. Indeed a standard compiler optimisation is to un-roll the loop to produce linear code... which in itself may make things better or worse.
In case the inner code is just a single cycle. Which it often is not. The loop support code is basically constant in size and execution time. So with any non-trivial loop contents it becomes irrelevant. In case of a single instruction loop I would expect the compiler to unroll it anyway, and I probably wouldn't care. Because...

If you are at all in doubt: KISS. You can usually find at least some time to optimise and beautify code once it's working, bosses love working code.
That's exactly right. I would write the loop. It's simple, readable and maintainable. In case it is too slow and doesn't work, then I would unroll it by hand. "Premature optimization is the root of all evil", as the mantra goes.

Also, if you really want to have it unrolled... at least define a macro/inline function for it, more readable and can be easily changed around.
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #13 on: January 29, 2012, 06:32:28 pm »
The compiler will generate something similar to the following pseudo code...

No, it might or might not. Modern compilers are rather unpredictable in what they produce when they are really pushing optimization hard, and the good ones do push optimization hard.

Decades ago it was different. Back then C compilers promised much but couldn't deliver much optimization. These days however, I often shit my pants when studying optimized C compiler output. On a good day a good C compiler approaches hand written assembler quality in some parts. On a bad day they still mess things up.

As a consequence I have long given up on trying to second-guess what a compiler does. Especially I refrain from trying to "help" the compiler when coding. Help only gets in the way of the compiler's optimizer. The only exception is when a particular piece of code turns out to be too slow or too large. When I have hard measurements showing this, not just a gut feeling. Then, and only if it matters, I try to trick the compiler into doing better. It happens fewer and fewer over the years.

BTW, One error you have in your analysis is thinking output() is a single instruction cycle. In the current case (Arduino code) it is a call to a rather messed up function in the Arduino library. That alone can lead a compiler's optimizer to completely different conclusions.

BTW2: If you want to really unroll something, tell the compiler to do it. Usually the compiler makes less errors than the user, e.g. not missing two loop cycles :-)
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline baljemmett

  • Supporter
  • ****
  • Posts: 665
  • Country: gb
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #14 on: January 29, 2012, 06:51:13 pm »
As a consequence I have long given up on trying to second-guess what a compiler does. Especially I refrain from trying to "help" the compiler when coding. Help only gets in the way of the compiler's optimizer. The only exception is when a particular piece of code turns out to be too slow or too large. When I have hard measurements showing this, not just a gut feeling. Then, and only if it matters, I try to trick the compiler into doing better. It happens fewer and fewer over the years.

Yes indeed; describe what you're trying to do in your code, and let the compiler worry about the best way to turn it into an instruction stream.  It'll usually get it right, and when you can prove it doesn't there'll be a way to give it a prod in the right direction.  See also Knuth's famed line, "premature optimisation is the root of all evil".

(Which reminds me, I have a section of code that I thought was quite straightforward but the Hi-Tech compiler suggests might make a nice addition to their validation suite.  That was quite a surprise; must send it off and see what they make of it.)
 

alm

  • Guest
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #15 on: January 29, 2012, 07:18:24 pm »
Code: [Select]
    i = 0;
for_begin:
    if( !( i < 8) )
        goto for_exit;
    output( i );
    ++i
    goto for_begin;
for_end:

Real assembly from avr-gcc is more something like this:
Code: [Select]
    i = 8;
for_begin:
    do_something();
    if (--i) goto for_begin;
The if and goto represent two assembly instructions; two or three cycles.

d1) If you have a working branch predictor then this may take one or two cycles. If you have a pre-fetch buffer or cache then the jump may or may not require a new set of fetch cycles.
How many 8-bit micros have a brench predictor or pre-fetch buffer? The SRAM is simply running at the same speed as the ALU, so no need for caching or complicated pipelines. This means that jumps are quite cheap. On CPU's with long pipelines and complex caching strategies, it may get even more complicated, because unrolling a loop may prevent your code from fitting in the instruction cache, which can carry a huge performance hit.

A simple for loop may be 5 or 10 times slower than the equivalent linear code. Indeed a standard compiler optimisation is to un-roll the loop to produce linear code... which in itself may make things better or worse.
In the worst case with a single cycle output instruction it would be three to four times slower in my example. In many cases (like in the Arduino library) it's likely to take longer (you may have to toggle a clock line for example), so the relative overhead is reduced even further.

It is unwise to make a blanket call without considering the underlying cpu architecture + cache + predicters.
Exactly. This is why it's usually unwise to second-guess the compiler unless you've done the research (eg. looked at the disassembly listing) or are an expert at that particular MCU architecture.
 

Offline desowin

  • Contributor
  • Posts: 21
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #16 on: January 29, 2012, 07:35:48 pm »
As others already mentioned using loop there could be nice, I'll throw in my two cents about the unnecessary assignment. I believe the temp = value; before sending each data bit is redundant. The value of temp is not going to change in the meantime (and even if value changes in some interrupt, it's bad idea to use part of old and part of new value).
« Last Edit: January 29, 2012, 07:43:56 pm by desowin »
 

Offline remoteledger

  • Newbie
  • Posts: 2
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #17 on: January 29, 2012, 07:56:25 pm »
Just sharing my experience with SPI. This is common to misconfigure data capture mode. Microcontroller allows you to set data capture on raising clock or on falling clock. So if controller thinks that receiver will accept data on falling clock and actual receiving device accept it on raising clock, then you'll get nasty data corruption it the best or no communication at worse.
 

Offline ndictuTopic starter

  • Regular Contributor
  • *
  • Posts: 211
  • Country: sk
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #18 on: January 29, 2012, 08:30:53 pm »
As a consequence I have long given up on trying to second-guess what a compiler does. Especially I refrain from trying to "help" the compiler when coding. Help only gets in the way of the compiler's optimizer. The only exception is when a particular piece of code turns out to be too slow or too large. When I have hard measurements showing this, not just a gut feeling. Then, and only if it matters, I try to trick the compiler into doing better. It happens fewer and fewer over the years.

Nicely said. Unless you really need the compiler to output some specific code, just do what is easiest, most readable etc. When you need some optimization, you can suggest it using compiler flags or keywords like inline (not sure about AVRs, but from I've read about modern x86/x86_64 compilers, they just ignore the inline altogether and decide themselves if it's a good optimization or not).

And of course, if you really, really need to micromanage the code, throw in a block of assembly. But that should be the last resort.
 

Offline ndictuTopic starter

  • Regular Contributor
  • *
  • Posts: 211
  • Country: sk
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #19 on: January 29, 2012, 08:42:16 pm »
As others already mentioned using loop there could be nice, I'll throw in my two cents about the unnecessary assignment. I believe the temp = value; before sending each data bit is redundant. The value of temp is not going to change in the meantime (and even if value changes in some interrupt, it's bad idea to use part of old and part of new value).

Except the first temp = value; line, all others are redundant. (temp>>x) will just return the value and leave temp unchanged. As for the first one, I think it wasn't visible in the video where that came from, but I suppose it's a parameter to that function. In that case the temp variable is completely redundant.

Dave: maybe you could publish the code somewhere (either just on the website; or preferably, in the long run, on some VCS hosting like github, bitbucket, google code etc). Software is something that can be easily collaborated over net, and people could start making improvements, bug fixes and adding features already.

The good thing about for example github is that you get a visible list of all forks made by participants, and they can also send you pull requests. You can review each one and decide whether to incorporate it into your "official" repository (eg. bugfix), or not (eg. some personal preference about display style, features, ...).

Of course, like everyone had their own vision of the schematic/pcb, this will probably end with a lot of people arguing over it. So maybe just put it on the site for now.
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #20 on: January 29, 2012, 08:59:47 pm »
I don't think it's worth the time or trouble to get worked-up about Dave's code at this point.  If I were to guess I would say he simply hacked something together just to test the board. 

The code you saw in the video will likely change significantly by the time all is said and done.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 12398
  • Country: us
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #21 on: January 29, 2012, 10:00:16 pm »
The last thing to do is open up a discussion over code. People will get into deep discussions and nit pick over the tiniest things, as has happened in this thread. If you think that happens over hardware designs, just wait and see how much worse it is over software. Every man and his dog is a software expert...  ;D
 

Online EEVblog

  • Administrator
  • *****
  • Posts: 38715
  • Country: au
    • EEVblog
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #22 on: January 29, 2012, 10:18:41 pm »
Dave: maybe you could publish the code somewhere (either just on the website; or preferably, in the long run, on some VCS hosting like github, bitbucket, google code etc). Software is something that can be easily collaborated over net, and people could start making improvements, bug fixes and adding features already.

No. This is a dictatorship, I'll code the way I like, no one else gets any say in it until it's released  :P

Dave.
 

Offline firewalker

  • Super Contributor
  • ***
  • Posts: 2452
  • Country: gr
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #23 on: January 29, 2012, 10:31:13 pm »
Dave, when you started the video the light was quite bright (I like it). At some time it dimmed. Do you use a spotlight and turned it off for the laptop's screen capturing?

Alexander.
Become a realist, stay a dreamer.

 

Online EEVblog

  • Administrator
  • *****
  • Posts: 38715
  • Country: au
    • EEVblog
Re: EEVblog #240 - Power Supply Design Part 8
« Reply #24 on: January 29, 2012, 10:33:54 pm »
The last thing to do is open up a discussion over code. People will get into deep discussions and nit pick over the tiniest things, as has happened in this thread. If you think that happens over hardware designs, just wait and see how much worse it is over software. Every man and his dog is a software expert...  ;D

Yup, order of magnitude worse than hardware...
I wonder if anyone if foolish enough to do a software coding video blog?

Dave.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf