Archives for: June 2006

06/27/06

Real life got no Lost&found

So, someone hanging around here in Villanova (or maybe still sleeping, who knows?) got my keychain card thing. It'd be pretty cool if he/she could give it back, so I can at least have food tomorrow...

wingo, yours is at the Fluendo booth in the main building.

Permalink . Ikke . 01:28:53 pm . 48 Words . Life . . 760 views . 4 comments

06/16/06

Regarding string duplication

This entry might bore most of you, upset some others, and could be useful for some. Sorry!!!

Last 3 days I've been reading (in my study pauses ;-)) on code optimalisation (both code speed and memory) and DSO pitfalls (pointers and some samples might follow later).

One of the things I read was a paper by Ulrich Drepper (Glibc guy), where one of the samples was about string duplication (strdup) optimalisation.

I looked into the Glib (no, thats not glibc) code to see how it was handled there, and found a simple, straight-forward, (unoptimized) implementation.
So obviously, I wanted to find out if this could be somewhat optimized. So I started my precious gvim, and made a testcase, which does some (well, a lot of) different duplications, both using g_strdup and my own little implementation.

An overview of what the test code does:

  • Do one simple strdup using g_strdup, and free the result (so the test is "fair", think of relocation time)
  • Copy, print and free a compile-time constant string, a variable string (argv[0]), and an empty string (strlen printed here) to make sure the code works fine
  • In a loop of 10000000 iterations, duplicate a constant string, a variable one (again, argv[0]) and an empty one, and free them

Why always a constant string, a variable one and an empty one? Simply because my implementation tries to handle these cases in the most efficient way ;-)

Here's the result:

nicolas@marslander ~/tmp $ gcc -o my_strdup_test -O2 `pkg-config --cflags --libs glib-2.0` g_strdup_test.c
g_strdup_test.c:9:10: warning: #warning "Using own implementation"
nicolas@marslander ~/tmp $ gcc -o g_strdup_test -O2 `pkg-config --cflags --libs glib-2.0` g_strdup_test.c -DUSE_G_STRDUP
g_strdup_test.c:5:10: warning: #warning "Using g_strdup"
nicolas@marslander ~/tmp $ ./g_strdup_test > /dev/null && echo -e "g_strdup_test:\n==============" && time ./g_strdup_test && ./my_strdup_test > /dev/null && echo -e "my_strdup_test:\n===============" && time ./my_strdup_test
g_strdup_test:
==============
foo = foo
./g_strdup_test = ./g_strdup_test
0 = 0

real    0m9.438s
user    0m8.968s
sys     0m0.064s
my_strdup_test:
===============
foo = foo
./my_strdup_test = ./my_strdup_test
0 = 0

real    0m5.906s
user    0m5.627s
sys     0m0.033s

I know 'time' is not a very good benchmark, but I guess the result is fairly obvious.
This result is +- the average, g_strdup version ranging between 9.4 and 9.6 seconds, mine between 5.8 and 6.1 seconds. This is a 30-40% speed gain, not wasting more memory.

Obviously, not all duplications would become faster. Actually, only the ones of strings which are constant at compile-time. In some applications this can be a major amount of g_strdup calls though.

I should note this "enhancement" is only possible when GCC is used as compiler as it uses some GCC-specific extensions. This is not an issue though, as on other compilers the code won't become slower :-)

The code I used can be found here. I added comments to make some things easier to understand (I hope), but the code is not "clean". A check for GCC should be added etc, but hey, this is just a proof of concept.

I really like these rather low-level optimisation things. They allow a lot of applications to become more efficient without changing the actual app, and low-level code is fun.
I'll read some more about this, and try to blog about interesting papers/techniques/... too, got some things in mind, but lack time now (yeah, those exams).

Luckily the end is in sight, and so is GUADEC :-) Booked my plane some days ago, still awaiting one email about lodging stuff. I'm so glad and thankful I'll be able to be there. Great start of holidays ;-)

Enough now, more algebraics and geometry to learn...

Permalink . Ikke . 07:30:53 pm . 645 Words . Linux, Coding Corner . . 968 views . 3 comments

06/14/06

Maemo/Nokia 770 sound streaming

As I'm not allowed to code last days (studies >:() I tried to get something working I wanted for a long time: be able to run my favorite media player on my desktop (I must confess that's Amarok), and playback the music using a hifi chain in another room.

As currently I don't have a wifi network at home, I can't do "the real thing" yet, but testing can be done using usbnet (little howto on how to set up that might follow later).

After lots of searching and great help on several IRC channels, I got things working fine now.

Let's start with a little overview of the setup.
Desktop:

  • Music player: Amarok using the Xine backend, using alsa
  • Streaming server: Icecast2
  • Icecast source: gst-launch using the shout2cast sink

770:

  • Just the standard audio player

Here's how to set up things correctly:

  • Install icecast2 on your system (this is distribution dependant)
  • Configure the server. You can run icecast as a system service, or as a normal user. I chose to run it as a normal user:
    • Copy /etc/icecast2/icecast.xml to some directory
    • Change "logdir" to some directory you got write permissions for
    • Start the server: icecast -c icecast.xml (add -b to daemonize)
  • Start some media player
  • Now we got to get the media player's output to our icecast server. As the 770 cannot playback ogg/vorbis, but can handle mp3, we'll use mp3 here. I know that might be non-free etc, but let's be pragmatic.

    To get the alsa sound to the server, one might use DarkIce, but I could not get this working, so I used a simple gstreamer pipeline instead:gst-launch-0.10 alsasrc device=plughw:0,0 ! audioconvert ! lame ! shout2send mount=amarok

    You might need to change the "device" parameter, you can change the "mount" parameter of shout2send too (although you'll have to adjust the URI used later too, of course). I'm using the default password ("hackme") in this setup, if you don't, or want to set other options, see gst-inspect-0.10 shout2send for more info.

  • When that's running fine, open a browser, and go to http://localhost:8000. If all goes well, the "amarok" mount should be listed there. Do not open the stream, as this'd create a loop!
  • Finally, launch the audio player on your 770 device, open the menu, "Playlist -> Add Stream...", and enter here the URI of the stream. In my setup, this is http://192.168.2.1:8000/amarok. Now start playback.
  • The 770 should buffer some data, then start playback.

Currently, I stream my Amarok's output to my device using usbnet, and got my normal computer speaker connected to the jack output. Works fine :-)

If you're using Amarok too, take a look at the "Web Control" script. When running this script, you can open the 770's browser, and browse to http://192.168.2.1:4774 (adjust the IP). Now you're able to control Amarok from your device, and look at the current playlist. No need to walk to your desktop. The web interface might need some love though.

That's about it, have fun!

Permalink . Ikke . 12:06:05 pm . 507 Words . Networks, Desktop . . 6608 views . 4 comments