Oversampling in VMD

User avatar
ChR_is
Posts: 106
Joined: Wed Sep 22, 2021 5:48 pm

Re: Oversampling in VMD

Post by ChR_is »

modern compilers and modern CPUs are pretty hard to understand tbh. especially java, because java isn't compiled into machine code but into byte code that is run by the jvm with the jit changing it up on the fly. thus it's even harder to predict what your code ends up looking in instructions anyway.
the only way to evaluate performance is benchmarking and tracking imho. i do a lot of benchmarking for obscure optimizations ;D
it's also a good idea to have a performance meter on your module, because code in isolation might behave differently when put into a module context. i'll put my performance meter into R_OpenLib soon.

as a rule of thumb, i try to avoid branching, (huge) caches, division/modulo and locks as much as possible.

what's worth mentioning at this point is that java can't actually accurately track nanoseconds, so take these measurments with a grain of salt. and if you do benchmarking, make sure to run the benchmark long enough so the jit can settle.

i'm on an AMD Ryzen 5 3600x, but i also benchmark on an laptop with an AMD Ryzen 5 5500U.

but i still agree with you, @ColinP. for an example project i should have used the more straightforward way. performance doesn't matter in an example anyway. it would have made it easier to understand.
ColinP
Posts: 951
Joined: Mon Aug 03, 2020 7:46 pm

Re: Oversampling in VMD

Post by ColinP »

Broad agreement, however benchmarking and profiling have their limitations too because different processors behave differently and it's impossible to predict how future ones might behave.

Chris, one thing I'd be fascinated by is if you could make a simple mod and run a sine wave rather than noise through your test bed. It would give us an idea of the impact of branch prediction on all of this.

For anyone who doesn't know how sophisticated branch prediction has become take a look at this wiki page...

https://en.wikipedia.org/wiki/Branch_predictor
User avatar
ChR_is
Posts: 106
Joined: Wed Sep 22, 2021 5:48 pm

Re: Oversampling in VMD

Post by ChR_is »

with a non-clipping sine

Code: Select all

  for( int i = 0; i < 480; ++i )
  {    
    //double value = 13 * Math.random() - 7;
    double value = Math.sin( Math.PI * 2 * (double)i/480.0 );
    valuesIf[i] = value;
    valuesObs[i] = value;
  }
the results are a lot better for the IF-method, but still about half as efficient as the obscure method.

Code: Select all

ifs avrg:      445,3619
Obscure avrg:  182,0838

ifs avrg:      442,1926
Obscure avrg:  171,1903

ifs avrg:      443,9414
Obscure avrg:  174,0585
by adding a factor to the sine so it is actually clipped by the clipping functions

Code: Select all

  for( int i = 0; i < 480; ++i )
  {    
    //double value = 13 * Math.random() - 7;
    double value = 2.0 * Math.sin( Math.PI * 2 * (double)i/480.0 );
    valuesIf[i] = value;
    valuesObs[i] = value;
  }
  
the IF-implementation takes a performance hit, wheres the obscure method stays roughly the same

Code: Select all

ifs avrg:      604,6308
Obscure avrg:  173,6244

ifs avrg:      607,8882
Obscure avrg:  169,4262

ifs avrg:      604,6530
Obscure avrg:  168,5240
interestingly though, when the signal gets more complex, but is still very periodic, the cpu load increases in the same way for both methods

Code: Select all

  for( int i = 0; i < 480; ++i )
  {    
    //double value = 13 * Math.random() - 7;
    double value = 2.0 * Math.sin( Math.PI * 2 * (double)i/480.0 ) * Math.sin( Math.PI * 3 * (double)i/480.0 );;
    valuesIf[i] = value;
    valuesObs[i] = value;
  }
  

Code: Select all

ifs avrg:      623,8803
Obscure avrg:  191,9810

ifs avrg:      612,8871
Obscure avrg:  179,4148

ifs avrg:      618,0618
Obscure avrg:  181,0231
all in all, very hard to predict the actual impact but the branching is always the slower options. at least in these tests.
ColinP
Posts: 951
Joined: Mon Aug 03, 2020 7:46 pm

Re: Oversampling in VMD

Post by ColinP »

Cheers Chris,

Wow, your speed is truly impressive, I'm guessing you are in your mid to late 20's.

Those results kind of confirm that branch prediction makes a big difference as the IF results are much better for more "real world" like signals compared with noise, as I expected.

I'd therefore hazard that the obscure version is more optimal because the abs() aren't branched but done in hardware...

Code: Select all

	load register 1 with value
	add 1 to register 1
	absolute op on register 1
	load register 2 with value
	subtract 1 from register 2
	absolute op on register 2 
	subtract register 2 from register 1
	multiply register 1 by 0.5
So the whole thing becomes 8 cycles but without any branches to mess with the pipelining.

It will be interesting to see what happens with forthcoming CPUs as I expect more speculative execution so one day the intuitions of veterans like me might work again!

By the way although Java uses intermediate code and a stack model I think this is converted to a native register based model when Hotspot does it's JIT magic so thinking about the code at a register level might still make sense.

One final point that might not be clear to some is that (I think) your hardclip process only clips if signals are greater than the regular +/- 5 V VM signal levels so perhaps the 0.2 and 5.0 scaling factors should be adjusted so people can hear the effects using regular signals?

Just in case it's not obvious due to my nitpicking, misunderstanding and limited social skills, I'm really grateful for your contribution here and greatly impressed by your work and generosity.
poetix
Posts: 54
Joined: Mon Nov 28, 2022 3:26 pm

Re: Oversampling in VMD

Post by poetix »

I'm puzzled by the description of the R_Ware Oversampler - https://store.cherryaudio.com/modules/r-oversampler - because it seems to imply that it's pushing samples through other modules at a higher sample rate than the standard patch cable linking would enable. Is it actually doing that (and if so, how?). If it's not doing that, then what's actually happening?
London, UK
Developer, Vulpus Labs
Musician, w/trem
User avatar
ChR_is
Posts: 106
Joined: Wed Sep 22, 2021 5:48 pm

Re: Oversampling in VMD

Post by ChR_is »

poetix wrote: Wed Jan 18, 2023 9:52 pm I'm puzzled by the description of the R_Ware Oversampler - https://store.cherryaudio.com/modules/r-oversampler - because it seems to imply that it's pushing samples through other modules at a higher sample rate than the standard patch cable linking would enable. Is it actually doing that (and if so, how?). If it's not doing that, then what's actually happening?
It is not pushing more samples through one cable. it provides an upsampler and downsampler in modular form. the oversampled signal is provided at multiple outputs and must be fed through multiple instances of the same module and then routed back into the R_Oversampler.
there's a picture here where it is set up: https://store.cherryaudio.com/modules/r-oversampler
there's also a tutorial preset pack which shows you how to set it up: https://store.cherryaudio.com/presets/r ... s-tutorial

Hope this helps

btw. the IIR option in this module is very similar to the IIR oversampling code in R_OpenLib ;)
poetix
Posts: 54
Joined: Mon Nov 28, 2022 3:26 pm

Re: Oversampling in VMD

Post by poetix »

Ah, I get it - parallelisation! Very clever…
London, UK
Developer, Vulpus Labs
Musician, w/trem
Post Reply

Return to “Module Designer”