Hi all,
Just wondering why hsv2rgb.pd (which is pretty incomprehensible) isn't a compiled external. I had to write a C implementation because the Pd implementation was too slow. Some rough benchmarks:
CPU: 1.6GHz Pentium-M Patch: rather complex, with 25*1024 calls to hsv2rgb per second. CPU-load as reported by load-meter.pd: hsv2rgb.pd : 108% fast_hsv2rgb.c : 94%
Quite a difference.
Note that fast_hsv2rgb.c is coded really unsafely, doesn't check argument counts/types/ranges/etc - use at your own risk.
Thanks,
Claude
On Tue, Dec 11, 2007 at 11:03:56AM +0000, Claude Heiland-Allen wrote:
Just wondering why hsv2rgb.pd (which is pretty incomprehensible) isn't a compiled external. I had to write a C implementation because the Pd implementation was too slow. Some rough benchmarks:
Hi Claude,
As the resident abstractions-over-externals obsessive, I feel I should put forward an argument to the contrary, just for good measure. Basically it goes like this: CPU is getting cheaper, but programmer time is getting more expensive (or put a different way; i'd rather make the computer do work than myself do work). My implication is that editing an abstraction is easier than editing & compiling an external, which could well be wrong, but there it is.
Best,
Chris.
------------------- http://mccormick.cx
Hallo, Chris McCormick hat gesagt: // Chris McCormick wrote:
As the resident abstractions-over-externals obsessive, I feel I should put forward an argument to the contrary, just for good measure.
A speed comparison with a lua/python implementation would be interesting. You'd still be able to quickly change it or use it as a base for other objects without recompiling.
Ciao
Hallo, Frank Barknecht hat gesagt: // Frank Barknecht wrote:
Chris McCormick hat gesagt: // Chris McCormick wrote:
As the resident abstractions-over-externals obsessive, I feel I should put forward an argument to the contrary, just for good measure.
A speed comparison with a lua/python implementation would be interesting. You'd still be able to quickly change it or use it as a base for other objects without recompiling.
Okay, I wrote a quick one using the markex code as a starting point. It would be interesting to benchmark this with Claude's patch against the pd-abstraction. (There's also a pdlua question for Claude hidden inside.)
Ciao
Hallo, Frank Barknecht hat gesagt: // Frank Barknecht wrote:
Okay, I wrote a quick one using the markex code as a starting point. It would be interesting to benchmark this with Claude's patch against the pd-abstraction. (There's also a pdlua question for Claude hidden inside.)
Okay++: I benchmarked it, and Pd is slightly faster and I'm disappointed. ;)
Could this be because Lua calculates double precision? Maybe I'll benchmark again with LUA_NUMBER set to float.
Ciao
Hallo, Frank Barknecht hat gesagt: // Frank Barknecht wrote:
Okay++: I benchmarked it, and Pd is slightly faster and I'm disappointed. ;)
Could this be because Lua calculates double precision? Maybe I'll benchmark again with LUA_NUMBER set to float.
Okay+++: With single precision, lua finally beats Pd and is about a fifth faster. I'm relieved, however that brings up the questions, if I should use lua with single precision in Pd? What would I loose (besides precision)?
Ciao
On Dec 11, 2007 10:35 AM, Frank Barknecht fbar@footils.org wrote:
Okay+++: With single precision, lua finally beats Pd and is about a fifth faster. I'm relieved, however that brings up the questions, if I should use lua with single precision in Pd? What would I loose (besides precision)?
For color data floating point is already overkill.
I should also point out that HSV/HLS/HSB/etc is not a useful color space to deal with. Excellent details as to why are provided by Charles Poynton:
http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC36 http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html#HSI
If you need brightness or saturation then use YUV which properly accounts for non-linear aspects of color. The 'hue' part of HSV is worthless.
On Tue, 11 Dec 2007, chris clepper wrote:
On Dec 11, 2007 10:35 AM, Frank Barknecht fbar@footils.org wrote:
Okay+++: With single precision, lua finally beats Pd and is about a fifth faster. I'm relieved, however that brings up the questions, if I should use lua with single precision in Pd? What would I loose (besides precision)?
For color data floating point is already overkill.
One of PdConvention2007's papers talked about the use of floating-point with image data. It was the paper on FFT. For that case, it's not overkill, unless you consider a more complicated integer-based solution as not being overkill, which is something I'd dispute.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
Lua is not really good for doing matrix processing within the script in realtime as it will incur all kinds of overhead. It's best instead to deal with a matrix userdata type with arithmetic metamethod calls defined. This will be really fast and completely dynamic.
wes
On Dec 11, 2007 8:35 AM, Frank Barknecht fbar@footils.org wrote:
Hallo, Frank Barknecht hat gesagt: // Frank Barknecht wrote:
Okay++: I benchmarked it, and Pd is slightly faster and I'm disappointed. ;)
Could this be because Lua calculates double precision? Maybe I'll benchmark again with LUA_NUMBER set to float.
Okay+++: With single precision, lua finally beats Pd and is about a fifth faster. I'm relieved, however that brings up the questions, if I should use lua with single precision in Pd? What would I loose (besides precision)?
Ciao
Frank Barknecht _ ______footils.org__
GEM-dev mailing list GEM-dev@iem.at http://lists.puredata.info/listinfo/gem-dev
BTW, if you're on an Intel machine, you can use LuaJIT to get a significant speed boost on looping structures and numerical calculations. wes
Hallo, Wesley Smith hat gesagt: // Wesley Smith wrote:
Lua is not really good for doing matrix processing within the script in realtime as it will incur all kinds of overhead. It's best instead to deal with a matrix userdata type with arithmetic metamethod calls defined. This will be really fast and completely dynamic.
Thanks for these hints. I actually had my benchmark wrong as well, and even with floats, Lua was slower than Pd in that case, even sigificantly slower.
However Pd also doesn't use any special matrix ops in the hsv2rgb abstractions. Basically the conversion is just a rather small bunch of additions and multiplications, and still pdlua here was slower. This is similar to [expr] being slower than an explicitly coded Pd patch.
OTOH some benchmarks I did with GL operations in Lua showed Lua to be quite a bit faster than Gem/Pd.
Do you have some further hints where Lua may not be appropriate compared to patching Pd directly?
Ciao
Well, Lua really shines for dynamic and generative systems. Try making dynamics graphics with polyphony in Pd and see how far you get. Things I wouldn't do _directly_ in Lua include video processing, DSP, etc. basically things with iterations over lots of data and intensive math ops. That said, I would still do them in Lua, but I would do them via C/C++ bindings that handle all of the really processing intensive work.
My basic approach to Lua is to use it as a sketching interface first and figure out how I want things to work and then once I get a feel for it, move certain sections down to C/C++. When you make this transition, it's best to generalize so that you can reuse it later. I do this for intensive operations like matrix processing, vector-ops, buffer drawing etc. First thing to do is get yourself some good vector math and quaternion bindings. I use these all the time and they save me a ton of work. I can send you a nice quaternion lib if you need it. Also, get yourself some mid-level OpenGL abstractions bound to Lua as userdata like Textures, Shaders, FBOs, etc that handle all of the dirty work under the hood and provide a clean interface to Lua. For example, here's some render-to-texture and post processing code as I typically use it in my own code:
local scene = Texture(1024, 768) local blurred_scene = Texture(1024, 768) local slab = Slab("blur.glsl") slab:param("width", {2, 2})
scene:begincapture(0) //draw scene here scene:endcapture(0)
slab:draw(scene, blurred_scene)
blurred_scene:bind(0) gl.Begin("QUADS") //draw a quad with tex coords gl.End() blurred_scene:unbind(0)
So, using a few higher-level C++ objects, you make make really concise scripts that do quite a bit. As you can see, it's really simple to render to a texture and apply effects to it given a representation of a Texture and a Slab. What's nice is that the slabs and can be arbitrarily chained together for more complicated effects and feedback with delay lines of varying length. The code for doing this stuff should be ready to share come the new year.
Taking this method to the extreme a friend of mine has made a scriptable DSP system using Lua called Vessel which is bundled into the Lua~ max external. The source is available and could easily be built into a pd external. See: http://www.mat.ucsb.edu/%7Ewakefield/lua%7E/lua%7E.htm .
If you're interested in discussing Lua for audiovisual composition, we've established a mailing list on the Media Arts and Technology servers here at UC Santa Barbara called lua-av ( http://zydeco.mat.ucsb.edu/mailman/listinfo/lua-av ). Feel free to sign up. There's very little traffic on it right now, but then again there are only about 5 people on the list. I don't think there are that many people doing audiovisual work with Lua right now anyway, but I anticipate more traffic once we get our standalone Lua-av software released and the utility of Lua for this kind of thing becomes apparent beyond the gaming industry. Most of the discussions about Lua and OpenGL right now are on the Jitter mailing list and it would be nice to consolidate these discussions into a central location that isn't Jitter, GEM, etc. specific.
best, wes
Hallo, Wesley Smith hat gesagt: // Wesley Smith wrote:
Taking this method to the extreme a friend of mine has made a scriptable DSP system using Lua called Vessel which is bundled into the Lua~ max external. The source is available and could easily be built into a pd external. See: http://www.mat.ucsb.edu/%7Ewakefield/lua%7E/lua%7E.htm .
I've seen this while browsing the lua~ page. Unfortunatly the license of the underlying synz lib you are using is not compatible with pdlua in requiring written consent of the original author. synz may be compatible with a non-GPL pdlua, but I'd prefer a real open source library.
Anyway, thanks for all your inspiring remarks. I'll go subscribe to lua-av - if alone to not get on the nerves of Pd and Gem people with Lua stuff too much. ;)
Ciao
I've seen this while browsing the lua~ page. Unfortunatly the license of the underlying synz lib you are using is not compatible with pdlua in requiring written consent of the original author. synz may be compatible with a non-GPL pdlua, but I'd prefer a real open source library.
Ah, I've asked the author to reconsider the license. I'll get back to you on that. wes
Hallo, Wesley Smith hat gesagt: // Wesley Smith wrote:
I've seen this while browsing the lua~ page. Unfortunatly the license of the underlying synz lib you are using is not compatible with pdlua in requiring written consent of the original author. synz may be compatible with a non-GPL pdlua, but I'd prefer a real open source library.
Ah, I've asked the author to reconsider the license. I'll get back to you on that.
That would be cool. As it is now, it's a real drawback: It effectively prohibits distribution of synz because everyone I'd give it to would be obliged to ask the author for written consent first. If the author suddenly decides to not write permissions anymore or isn't able to do so anymore, synz would be frozen and so would projects, that build on it. I don't think, that's what the author is intending.
Ciao
please frank, keep lua discussion also on the pd list! everything so far was really related to pd, and is important to know. marius.
Frank Barknecht wrote:
Hallo, Wesley Smith hat gesagt: // Wesley Smith wrote:
Taking this method to the extreme a friend of mine has made a scriptable DSP system using Lua called Vessel which is bundled into the Lua~ max external. The source is available and could easily be built into a pd external. See: http://www.mat.ucsb.edu/%7Ewakefield/lua%7E/lua%7E.htm .
I've seen this while browsing the lua~ page. Unfortunatly the license of the underlying synz lib you are using is not compatible with pdlua in requiring written consent of the original author. synz may be compatible with a non-GPL pdlua, but I'd prefer a real open source library.
Anyway, thanks for all your inspiring remarks. I'll go subscribe to lua-av - if alone to not get on the nerves of Pd and Gem people with Lua stuff too much. ;)
Ciao
Hallo, marius schebella hat gesagt: // marius schebella wrote:
please frank, keep lua discussion also on the pd list!
Don't worry, you know I can't keep my keyboard shut. ;)
Ciao
Well, Lua really shines for dynamic and generative systems. Try making dynamics graphics with polyphony in Pd and see how far you get. Things I wouldn't do _directly_ in Lua include video processing, DSP, etc. basically things with iterations over lots of data and intensive math ops. That said, I would still do them in Lua, but I would do them via C/C++ bindings that handle all of the really processing intensive work.
My basic approach to Lua is to use it as a sketching interface first and figure out how I want things to work and then once I get a feel for it, move certain sections down to C/C++. When you make this transition, it's best to generalize so that you can reuse it later. I do this for intensive operations like matrix processing, vector-ops, buffer drawing etc. First thing to do is get yourself some good vector math and quaternion bindings. I use these all the time and they save me a ton of work. I can send you a nice quaternion lib if you need it. Also, get yourself some mid-level OpenGL abstractions bound to Lua as userdata like Textures, Shaders, FBOs, etc that handle all of the dirty work under the hood and provide a clean interface to Lua.
This is essentially what I do too. I think pd/lua is interesting as you can have 3 layers of abstraction. You have more choice of when to move a piece of functionality to a different layer depending on what you are doing. I think the general rule should be keep it as high level as possible, and if you have to make it lower level make it as generic as possible (as you say).
It can be a really subtle desicion though - for example in fluxus now I'm restricting the grunt work in C++ to the critical path (for speed), and using Scheme where I need a more powerful language for the heavy lifting (eg collada import). It's hard to come up with hard and fast rules for what should be where - but if you have decent abstraction you can change your mind (move things up and down) without adversely effecting users with incompatibility.
cheers,
dave
On Tue, 2007-12-11 at 08:06 -0500, Chris McCormick wrote:
On Tue, Dec 11, 2007 at 11:03:56AM +0000, Claude Heiland-Allen wrote:
Just wondering why hsv2rgb.pd (which is pretty incomprehensible) isn't a compiled external. I had to write a C implementation because the Pd implementation was too slow. Some rough benchmarks:
Hi Claude,
As the resident abstractions-over-externals obsessive, I feel I should put forward an argument to the contrary, just for good measure. Basically it goes like this: CPU is getting cheaper, but programmer time is getting more expensive (or put a different way; i'd rather make the computer do work than myself do work). My implication is that editing an abstraction is easier than editing & compiling an external, which could well be wrong, but there it is.
Best,
Chris.
i highly agree with chris here. or i'd say the optimal solution would be to have both, abstraction and external (and as frank mentioned, there is already an external). speed is only an issue, when you do as many operations as you do. in many (the majority of?) cases it is probably used just to convert a value every one and then. i wouldn't want to deal with an extra external just for doing one conversion on loadbang.
roman
___________________________________________________________ Der frühe Vogel fängt den Wurm. Hier gelangen Sie zum neuen Yahoo! Mail: http://mail.yahoo.de
On Tue, 11 Dec 2007, Chris McCormick wrote:
As the resident abstractions-over-externals obsessive, I feel I should put forward an argument to the contrary, just for good measure. Basically it goes like this: CPU is getting cheaper, but programmer time is getting more expensive (or put a different way; i'd rather make the computer do work than myself do work).
The code for this is many years old and is small. The task to do does not change and the exact formulas are set. This is not the context in which one thinks about "programmer time getting more expensive".
My implication is that editing an abstraction is easier than editing & compiling an external, which could well be wrong, but there it is.
But why would you need to edit it?
But back to a more basic question: why do you want to use HSV ? it's that kind of weird hexagonal-pyramidal colourspace and that's one of the reasons why it's slower to process: you need to compute several "if" to get any value converted, and on modern processors, "if" is harder to optimise than anything else. But those same "if"s have other consequences: it makes the conversion formula bigger and somewhat harder to combine with other formulas. It's definitely not linear and not super close to any linear system.
if you do a polar transform on YUV, you have something easier, faster and more correct all at once. I usually just skip the polar transform: if you apply rotations directly on YUV values, you can make very believable hue shifts.
HSV is dubious in part because the apparent brightness at maximum so-called value is very variable and seems to peak high or low at secondaries or primaries: compare yellow (brightness 89%) and blue (brightness 11%). this really makes HSV suck sometimes. YUV does not have this problem.
_ _ __ ___ _____ ________ _____________ _____________________ ... | Mathieu Bouchard - tél:+1.514.383.3801, Montréal QC Canada
On Tue, Dec 11, 2007 at 01:47:25PM -0500, Mathieu Bouchard wrote:
On Tue, 11 Dec 2007, Chris McCormick wrote:
My implication is that editing an abstraction is easier than editing & compiling an external, which could well be wrong, but there it is.
But why would you need to edit it?
Yes, good question in this case.
Best,
Chris.
------------------- http://mccormick.cx
Hallo, Claude Heiland-Allen hat gesagt: // Claude Heiland-Allen wrote:
Just wondering why hsv2rgb.pd (which is pretty incomprehensible) isn't a compiled external.
It was and still is, but now in library "markex" which contains the old support objects from Gem (careful: also another counter!)
Ciao
Claude Heiland-Allen wrote:
Hi all,
Just wondering why hsv2rgb.pd (which is pretty incomprehensible) isn't a compiled external. I had to write a C implementation because the Pd implementation was too slow. Some rough benchmarks:
CPU: 1.6GHz Pentium-M Patch: rather complex, with 25*1024 calls to hsv2rgb per second. CPU-load as reported by load-meter.pd: hsv2rgb.pd : 108% fast_hsv2rgb.c : 94%
Quite a difference.
honestly i think that the difference is way less than i would have expected it. it means that a super-fast implementation in C using the latest compiler optimization and whatelse is only about 14% faster than a whole punch of indirection and overhead induced by pd's message parsing....
fgmasdr. IOhannes
IOhannes m zmoelnig wrote:
Claude Heiland-Allen wrote:
Hi all,
Just wondering why hsv2rgb.pd (which is pretty incomprehensible) isn't a compiled external. I had to write a C implementation because the Pd implementation was too slow. Some rough benchmarks:
CPU: 1.6GHz Pentium-M Patch: rather complex, with 25*1024 calls to hsv2rgb per second. CPU-load as reported by load-meter.pd: hsv2rgb.pd : 108% fast_hsv2rgb.c : 94%
nop.pd : 94%
Quite a difference.
honestly i think that the difference is way less than i would have expected it.
The benchmark wasn't clean - the patch was doing a whole bunch of other stuff at the same time. See revised benchmark above, and see below for a clean benchmark:
hsv2rgb.pd : 26900 cputime (including test source) [1] fast_hsv2rgb.c : 6730 cputime (including test source) [2] no object : 5750 cputime (test source) [3]
([1]-[3]) / ([2]-[3]) gives 21.8
C is almost 22x (2200%) faster than the Pd implementation of hsv2rgb.
Claude