Old 02-25-2019, 03:50 AM   #1
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: Germoney
Posts: 330
Default JSFX questions thread

First of all, JSFX is great. It's fantastic for getting something up and running _fast_. There are some things in the implementation of JSFX which I am curious about though. So far, I've mostly been treating it as a black box, trying to measure performance from the CPU meter where possible, but I would love to have some more insight into good JSFX coding practices.

1. Vectorization
Is any vectorization going on in JSFX? What kind of things should I avoid to make use of it, if so.

2. Function inlining. Are short functions inlined? Is it somehow possible to abstract away some stuff without taking a big perf penalty?

Say for instance I have a tanh, and I want to replace this with varying approximants based on some economy setting. Would I be forced to do several versions of the encompassing function which calls this tanh, or is the JSFX compiler smart enough to detect that the if-statement inside some function acts as the same switch for several calls.

3. Is it possible to go beyond the 64 slider limit? I've now been packing multiple settings in single sliders, but it is a bit of a meh solution as automating them makes no sense anymore now.
__________________
[Tunes] | [Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Github|Reapack] | [Filther: Thread|Github|Reapack]
sai'ke is offline   Reply With Quote
Old 02-25-2019, 06:55 AM   #2
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Germany
Posts: 6,617
Default

Short;: No / No / No.

What are you trying to accomplish ?
-Michael
__________________
www.boa-sorte.de
mschnell is offline   Reply With Quote
Old 02-25-2019, 07:26 AM   #3
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: Germoney
Posts: 330
Default

Thanks. I was just curious whether any SIMD vectorization was taking place and whether there were some agreed upon best practices for generating fast bytecode.

Partially because I was wondering if I could squeeze some more performance out of JSFX for some stuff I've been working on without rewriting it. And partially just because of curiosity.

Been working on a plugin which grew a bit bulkier than I initially intended it to be.
__________________
[Tunes] | [Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Github|Reapack] | [Filther: Thread|Github|Reapack]
sai'ke is offline   Reply With Quote
Old 02-25-2019, 10:16 AM   #4
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 11,854
Default

Short functions might be inlined, but it still results in temporary variables being made from parameters and prevents optimization across function boundaries.


There are some optimizations built in, for example constant expressions are usually reduced at compile time: 3*log(1+37/400) compiles down to 0.26540594396282 or whatever... (1 ? x : 3) compiles down to "x", etc. Memory accesses (x[y]) are a bit slow due to integer conversion+bounds checking.
Justin is offline   Reply With Quote
Old 02-25-2019, 04:41 PM   #5
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: Germoney
Posts: 330
Default

Thanks! That helps

Would it detect stuff like:

v = 1; /* settings const */
(v ? x : 3)

Probably not eh?

I really love the pseudo-objects by the way. They make a lot of things so much easier!
__________________
[Tunes] | [Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Github|Reapack] | [Filther: Thread|Github|Reapack]
sai'ke is offline   Reply With Quote
Old 02-25-2019, 06:40 PM   #6
Time Waster
Human being with feelings
 
Time Waster's Avatar
 
Join Date: Aug 2013
Location: Bowral, Australia
Posts: 809
Default

Re: 3, I assume you can go beyond 64 sliders if you make your own @gfx. As far as I can tell, the built in sliders are handy for automatically storing settings in the project, and for saving you a lot of graphics coding, but you can do the same (and more complex stuff) using indexed memory and @ serialize. Geraintluff has a library of stuff to do this, although I haven't looked at it closely.
__________________
ReaRack JSFX Modular Synth - Mostly harmless: https://stash.reaper.fm/v/28403/ReaR...dularSynth.zip
The Wasters of Time: https://soundcloud.com/thewastersoftime
Time Waster is offline   Reply With Quote
Old 02-26-2019, 09:28 AM   #7
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: Holland
Posts: 2,925
Default

Totally ignoring your 3 questions (because I have no answers for those), and therefore kinda off topic, but:

Quote:
Originally Posted by sai'ke View Post
but I would love to have some more insight into good JSFX coding practices
Well, here is a random "issue" I found a while back: There seems to be a tiny difference in performance between this

Code:
y = x*2*$pi;
and

Code:
y = x*(2*$pi);
The latter is smaller and more efficient. I guess JSFX treats the first as (x*2)*$pi, and so it doesn't optimize/replace 2*$pi with 6.2831853071795862.

Also, like Justin alreday said, integer conversion is relatively slow in JSFX, so n*2 will actually be faster than n<<1.

Another way of optimizing your code would be to look at code size (scroll down all the way to the stats in the IDE). Less code will not automatically mean faster code, but it could (should?) help.

Using functions seem to come with some overhead, so sometimes it helps to manually inline them.
Tale is offline   Reply With Quote
Old 02-26-2019, 11:14 PM   #8
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Germany
Posts: 6,617
Default

Quote:
Originally Posted by Tale View Post
Well, here is a random "issue" I found a while back: There seems to be a tiny difference in performance between this

Code:
y = x*2*$pi;
and

Code:
y = x*(2*$pi);
The latter is smaller and more efficient. I guess JSFX treats the first as (x*2)*$pi, and so it doesn't optimize/replace 2*$pi with 6.2831853071795862.
Interesting !

Will an intermediate variable be optimized out ?
Code:
pi2=2*$pi;
y=pi2*x;
thanks,
-Michael
__________________
www.boa-sorte.de
mschnell is offline   Reply With Quote
Old 02-27-2019, 01:50 AM   #9
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: Holland
Posts: 2,925
Default

Quote:
Originally Posted by mschnell View Post
Will an intermediate variable be optimized out ?
Code:
pi2=2*$pi;
y=pi2*x;
Well, you can try yourself:

Code:
desc:A
@init
pi2=2*$pi;
@sample
loop(1024,y=pi2*x);
Code:
desc:B
@sample
loop(1024,y=(2*$pi)*x);
Here A runs at 0.9% and uses 149+0 @sample-code, while B runs at 0.7% and 117+0. So it would seem that your pi2 doesn't get optimized to a constant, and also that loading a constant is faster and smaller than using a variable (I guess because a constant doesn't need to be evaluated each time it's loaded).

Note that for A you could move pi2=2*$pi into the loop. However, then it gets slightly slower and bigger, so I guess it means that it still doesn't get optimized away.
Tale is offline   Reply With Quote
Old 02-27-2019, 03:24 AM   #10
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: Germoney
Posts: 330
Default

Quote:
Originally Posted by Time Waster View Post
Re: 3, I assume you can go beyond 64 sliders if you make your own @gfx. As far as I can tell, the built in sliders are handy for automatically storing settings in the project, and for saving you a lot of graphics coding, but you can do the same (and more complex stuff) using indexed memory and @ serialize. Geraintluff has a library of stuff to do this, although I haven't looked at it closely.
slider65 doesn't get syntax highlighted, so I always assumed it didn't exist. I already render my own UI, but the reason I want them as sliders and not as serialized data is that I want to be able to automate them from the arranger. Of course, it would technically be possible to variably map sliders to internal data, but that seems a bit ugly.

I also don't think that non-slider serialized data is part of the presets. So the onus for storing banks of data would completely fall on me then. Since JSFX can't read/write files, presets would also not be shareable very easily anymore.

And thanks Tale, those are some good pointers! I didn't know you could see the generated code size. I will add this to the list of things to monitor while tweaking.
__________________
[Tunes] | [Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Github|Reapack] | [Filther: Thread|Github|Reapack]

Last edited by sai'ke; 02-27-2019 at 06:15 AM. Reason: remove wrong info
sai'ke is offline   Reply With Quote
Old 02-27-2019, 06:11 AM   #11
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: Holland
Posts: 2,925
Default

Quote:
Originally Posted by sai'ke View Post
I also don't think that non-slider serialized data is part of the presets.
Really? Because I'm pretty sure that serialized data is stored inside a RPL. There might be other issues though, e.g. reset to factory default seem to reset sliders only.
Tale is offline   Reply With Quote
Old 02-27-2019, 06:15 AM   #12
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: Germoney
Posts: 330
Default

Quote:
Originally Posted by Tale View Post
Really? Because I'm pretty sure that serialized data is stored inside a RPL. There might be other issues though, e.g. reset to factory default seem to reset sliders only.
Is it? Interesting. In that case, it might be a solution for at least part of my problems. Time to run some tests. Thanks!
__________________
[Tunes] | [Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Github|Reapack] | [Filther: Thread|Github|Reapack]
sai'ke is offline   Reply With Quote
Old 03-02-2019, 02:33 AM   #13
nitsuj
Human being with feelings
 
nitsuj's Avatar
 
Join Date: Nov 2017
Posts: 68
Default

Quote:
Originally Posted by sai'ke View Post
Is it? Interesting. In that case, it might be a solution for at least part of my problems. Time to run some tests. Thanks!
From what I can tell, you can have sliders > 64 but they don't serialise automatically and of course they don't show up in the UI. In other words, I think they just get recognised as another variable even though you can specify them with slider attributes. If they don't show up in the slider UI then you can't automate them.

Here would be my request for sliders having taken them to the limit:

1. Increase the number from 64 up to something much larger, maybe even as high as 1024. We're starting to see more feature rich JSFX that are blowing the limit.

2. Have it so that the upper slider display in a JSFX is contained in a scrollable panel and have the height optionally specified as a directive in the JSFX. This would allow either to have all sliders visible or to restrict to say the top quarter of the window if there are many sliders.

3. Normal VSTs have the option of viewing the graphic UI or the raw slider list. The raw slider list would be useful for JSFX for cases when we hide all of the sliders but still want to toggle to see and edit the sliders for debugging or automating.
nitsuj is offline   Reply With Quote
Old 03-02-2019, 05:37 AM   #14
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Germany
Posts: 6,617
Default

For several projects where I needed lots of sliders, I created a bunch of JSFXes, some of which (or instances of a single JSFX installed) are just used to show and store the "slider" values and the "functionality" JSFXes communicat with those via gmem.

-Michael
__________________
www.boa-sorte.de
mschnell is offline   Reply With Quote
Old 03-02-2019, 10:34 PM   #15
Time Waster
Human being with feelings
 
Time Waster's Avatar
 
Join Date: Aug 2013
Location: Bowral, Australia
Posts: 809
Default

From some testing I've been doing here, as long as you store the your custom slider output value in indexed memory and use file_mem() @serialize, the values will be saved with the preset. There may be other methods, but at least that one works.
__________________
ReaRack JSFX Modular Synth - Mostly harmless: https://stash.reaper.fm/v/28403/ReaR...dularSynth.zip
The Wasters of Time: https://soundcloud.com/thewastersoftime
Time Waster is offline   Reply With Quote
Old 03-03-2019, 07:53 AM   #16
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: Germoney
Posts: 330
Default

Quote:
Originally Posted by Time Waster View Post
From some testing I've been doing here, as long as you store the your custom slider output value in indexed memory and use file_mem() @serialize, the values will be saved with the preset. There may be other methods, but at least that one works.
Hey, yes, sorry, I forgot to report back. Indeed the state gets stored with the presets. Doesn't let you automate them then though. Spreading stuff over multiple plugs and communicating over gmem is possible but a bit nasty. It doesn't exactly benefit user friendliness.

Another option is to have rebindable sliders. Where one slider toggles a mode and the other sets the value. But again, this isn't super user friendly.

Anyways, JSFX is still really cool, and I can work around its limitations. The interactivity, pseudo objects and watch lists really make it a nice environment to tinker in. Thanks everyone
__________________
[Tunes] | [Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Github|Reapack] | [Filther: Thread|Github|Reapack]
sai'ke is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 09:50 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.