Tuesday, March 17, 2009

perly pie

Thats right, perl "-p -i -e"!

This command is your friend for replacing strings in a batch of documents at once. As I am not a frequent perl user I tend to forget the order syntax for specifying search/replace, but know the rough format contains a "/s" a "/" and a "/g". I tend to try out a quick command line version trial with stdin before going to the full replace. Today I did the test with

perl -p -i -e 's/goodbye/hello/g'

As it worked first try, I then accidentally used the above command in my "find" expression to do my desired replace (e.g., "find ./ perl -p -i -e 's/hello/goodbye/g' {} \;" ). I totally wasn't thinking, as I really wanted to replace occurences of an old host name in the ".svn/entries" files with a new one. Unfortunately, there were actually occurrences of hello in some binary files (I guess I had blender files with objects called hello). Blender then opened these screwed up files without error but containing no objects (the change in length must have 'effed the offsets in the binary). Luckily these were the only files affected and it was easy enough to change. In the future I'll have to make sure to replace the above command with the appropriate search/replace string and a "-name" to find.

OOps.

wxWidgets documentation

Last week I was porting a wxWidget application to the Mac, which shouldn't be all that painful, but I was having trouble with the application opening command line arguments.

Being one of the first GUI programs that used the command line for loading files, I didn't realize that the command arguments (e.g, "open -a myapp.app anargument", don't get passed in through argv/argc). After doing some digging, I turned up a reference for MacOpenFile in the wxPython port. I looked at the current versions documentation (wx 2.8.x) to see if this was something available in the c++ libraries as well. Didn't appear to be on their page (and doesn't come up if you search the site for MacOpenFile). WTF wxDocs?

Anyway, MacOpenFile does exist but just doesn't appear to be documented (in the common docs that is). It is really too bad because I suspect that most people would check wxApp first for alternatives methods to access command line arguments. Instead, you end up wasting time scouring the web for others with similar problems.

I meant to post this right after I had found the solution so I could tag the blog with all the things I had searched for. Unfortunately, I waited more than a week and no longer remember what I had searched.

Friday, March 6, 2009

float cast underflow slow

Today I noticed that some of code that just blended some images was being really slow dependent on some of the coefficients used in the blending. After checking the coefficients for strange values (nans/infs), for which there were none, it was still slow. The problem was only appearing in one function used for blending (some integer code that used floating coefficients that were casted from doubles). The problem didn't appear when strictly using floating point arithmetic. Turns out it is due to slow casting from double to float when there is underflow.

Some timing results for casting from double to double (d), double to float (f), double to integer (i), for test program, included below:

Without optimization
time for d (init=1e-30) 0.013476
time for f (init=1e-30) 0.012164
time for i (init=1e-30) 0.016217
time for d (init=1e-50) 0.019088
time for f (init=1e-50) 0.229608
time for i (init=1e-50) 0.019010

Without optimization (-O3)
time for d (init=1e-30) 0.005358
time for f (init=1e-30) 0.004038
time for i (init=1e-30) 0.003713
time for d (init=1e-50) 0.004566
time for f (init=1e-50) 0.135538
time for i (init=1e-50) 0.003527

You can see the floating point cast is something like 30x slower for the value of 1e-50 (where there is underflow) as opposed to the case of 1e-30 where there is no underflow.

Try the code for yourself.


#!/bin/sh

cat <<EOF > _f_.cc
#include
#include
#include
#include
#include

template
void test(int m, double init){
double * v = new double[m];
T * f = new T[m];
struct timeval tv;
gettimeofday(&tv, 0);

for(int its=0; its< 20; its++){
v[0] = init;
double * vptr = v;
for(int i=0; i< m; i++){
*(vptr++) = v[0];
f[i] = ((T)v[i]);
}
}
struct timeval tva, el;
gettimeofday(&tva, 0);
timersub(&tva, &tv, &el);
printf("time for %s (init=%g) %lf\n", typeid(T).name(), init, double(el.tv_sec) + double(el.tv_usec)/1e6);
delete [] f;
delete [] v;
}

int main(int ac, char * av[]){
int m = 100000;

test(m, 1e-30);
test(m, 1e-30);
test(m, 1e-30);

test(m, 1e-50);
test(m, 1e-50);
test(m, 1e-50);
return 0;
}
EOF

echo "Without optimization"
g++ _f_.cc -lm -o _f_
./_f_

echo "Without optimization (-O)"
g++ _f_.cc -lm -o _f_ -O
./_f_

echo "Without optimization (-O3)"
g++ _f_.cc -lm -o _f_ -O3
./_f_

echo "Without optimization (-O3)"
g++ _f_.cc -lm -o _f_ -O3 -mmmx -msse
./_f_

rm _f_.cc _f_

Tuesday, February 3, 2009

backtrace and friends

Just some notes on instrumenting code using gcc.

Add hooks before and after function calls with "-finstrument-functions" (__cyg_profile_func_exit, ...).

Several ways to look up symbols:

backtrace, backtrace_symbols

libbfd (library used by nm)

create your own symbol table (have macro to map function pointer to name).


On mac, atos is useful.

More to come.

Wednesday, January 28, 2009

WTF apple!

Just spent a long time (as in several hours) stumbling on things that shouldn't have even been problems.

1) Multi-touch on the iPhone. The freaking canvas has to have a property set to enable multi-touch. You still get multi-touch if you don't enable it, but the data is random--which makes you think that the scale and translation you are applying to your canvas is wrong. I see no good reason for having the option of turning off multi-touch events, so whoever decided that I want my wasted hour back.

2) OpenGL errors on the iPhone. Put in some glGetErrors to trace down the few errors I was having. Oddly enough they seemed to be right around the calls that used GL_CLIP_PLANE1 (not GL_CLIP_PLANE0, just clip plane 1). Sure, that didn't seem to be a problem before, but what'evs--I can deal with it. Still some other textures that looked wrong. Turns out I inadvertently created some non-power-of-two textures (which work fine in new versions of OpenGL now-a-days). As soon as I realized this I decided to double check the clip plane problem. Sure enough, no longer a problem. Why in the hell was an error being reported on the CLIP_PLANE1 and not somewhere closer to the texture. Damn, damn, double damn.

Sunday, January 18, 2009

And again



I found live ammunition on a bridge late last night. Made my day.

Still not much more luck with the lines. This rasterizes the current line, computes the signed distance from the line, extracts the level set at a specific distance, and then tries to connect the resulting polygons to the existing line. That's why the line appears to follow itself.

Slow. Downsampled they almost look like the embedded code images.



Wednesday, January 14, 2009

Line update



Some more lines. I have tried several different methods, and still nothing is giving me what I expect.


The code (which is a mess) because I wrote it at 3 in the morning is also embedded in the other not-so nice image (as usual).