I just saw a very interesting lecture by Davig Unger. Its main focus is the programming language Self, which is a prototyped-based object-oriented language. He also talks about other things: getting the right people to work with you, some of his guiding principles, and even a few comments on getting to know yourself.
David Ungar received the Dahl-Nygaard Senior Prize in 2009 for his work in the field of object-orientation, most notably for Self. He currenlty works at IBM Research.
Tuesday, March 30, 2010
Monday, March 15, 2010
Commodore 64 Live!
Do you remember those old arcade machines where, when no one played them, the "computer" would play the games? Kind of like a demonstration of the game instead showing some fancy graphics. I came across the übergeeky page C64 Longplays a few days ago and I feel that I must do my small part to spread the word through the world.
It's basic like those computer-played arcade machines, with the difference that it's actually someone who plays through the entire game. Didn't you solve the third level of Boulder Dash or did you think no one ever cared to finish Ghostbusters? Everything is on C64 Longplays for you to watch.
I personally liked the video of Yie Ar Kung Fu... some fights was really close... the energy bar was down to the last pixel!
Friday, March 5, 2010
The most important skill
As a software developer you need to have large skill set: knowing the right tools, languages, frameworks, platforms, and so on. To complicate things you need to keep every piece of knowledge updated since the field of computing is changing so rapidly. But what is the most important skill among all these? I argue that it's not knowledge of some key technology that make you more than an average programmer, nor is it how many fixed point combinators you dreamt up, how many open-source project you've started, or how fast you type. If non of these, what is the most important skill?
First let me note that with developer I do not mean someone like Alice who write shell one-liners for her husband Bob to search his photo collection of dogs with hats. I don't mean teenanger Charlie who uses barbed wire and duct tape to hack together scripts to play suitably random mp3s to match his parents' photo slide show from their vacation last summer. What I mean is someone who write code that other developers will maintain, test, read, enhance, etc. In essens I mean developers that work with other developers either directly or through their code.
So, the important part here is work with other developers, which leads me to the heart of this post: the most important skill for a developer is communication. Err, I'm sorry, let me correct that: the most important skill for every developer is effective communication. By communication I mean source code and comments, documentation and specifications, power-point presentations and white-board explanations, mail and phone calls, and so on. I could continue, but I think you've got the point.
A small disclaimer before we continue. I assume that the ones you communicate with want to understand what you say or write. If that's not the case then you have an entierly different problem, and I don't think much in this post can help you. Sorry. Ok, that's that, let's continue.
I've met many very technically skilled developers that, when I tell them I don't understand what you mean, literally repeated what they just said (only louder). Is this good communication? I don't think so. I've also got mails from otherwise good programmers which basically required mind reading ability in order to be understood. Even worse, the mails were sent to 10-50 people, meaning (10 to 50) * (mail length) / (reading speed) * (average speed reduction factor due to lack of mind reading ability) man-hours was spent reading that mail. Effective communication? No.
I think there are two kinds of communication: one-way and two-way. Explaning some intricate technical detail to you pair-programming collaegue is a two-way communication since you (should) instantly realize if you collaegue understands you (by her facial expressions and body language). Phone calls are also two-way since the vocal intonation (should) indicate directly to you whether or not your explanation is good enough.
On the other hand, I consider mail to be a one-way communication (especially if sent to many people) since you don't get any indications when you write the mail if it will be understood or not when received. The same is true for documentation, specifications, code comments and source code. All these kinds of communication is one-way since it takes long time until you get any feedback on if your colleagues understand it or not.
So, how to become a better developer? How to communicate more effectively? For two-way communication I suggest to practice. For one-way communication I suggest... practice, as well actually. That is. Move along, nothing more to see here. Hit the back-button on you favourite browser.
In fact, you could do this exercise by explaning anything. For instance, describe the story of the last book you read, a news article, or the story behind the best photo you ever took. But remember, you're not just telling the story, you're explaning what happend. You should "listen" (with your ears and eyes) to your audience to make sure they understand every word you say.
Some simple concrete tips:
- Be clear about the background. Just because you remember the context, does not mean every one else do. Start the explanation by giving the relevant context. If you have discussed it before with the audience, refer to that. If you haven't, start by giving a hand-waving overview of the problem.
- Use you hands. If you talk about many different objects, place them on different places in the air and "hold" the object you talk about by making a fist on that spot. Much less confusing for those who listen to you. Also, if you need to move your arms around to refer to different objects, you will probably speak more slowly which is also makes it easier to take in everything you say.
- Pop the stack explicitly. Often in a discussion you need to get back to something you talked about earlier. In that case, say "as I said before" before you start talking about it to indicate to your audience that you pop the conversation stack. If you just change the subject people could get a bit confused and miss some parts of your explanation.
- Be utterly clear when something is important. Say "this is the key point", or "this is important". Use short sentences. Repeat yourself. Use short sentences and repeat yourself. Make a pause to let your audience take in what you just said and let them think about it. Use some uncommon phrase or a silly name when explaning this key point that you can use later on to refer to it.
- Speak clearly or stay quiet. If you don't know what to say, don't mumble something incomprehensible. Just shut up. Scratch your head a bit if you feel akward to let the audience know that you're thinking about what to say. People won't mind anyway, unless you do it twice every minute. They will probably thank you for the moment of mental relief. In fact, you can make pauses like this work for your advantage. (Read the bullet above one more time if you don't understand why. (You still don't get it? I'm refering to the 6th sentence, silly.))
And oh, before I forget, say hello to aunt Mathilda for me!
Etiketter:
communication,
learning,
mail,
people,
skills
How browsers work
A former colleague sent me this very sweet explanation of how browsers work today. Can you say awww?
Thursday, February 25, 2010
Talks by Herb Sutter
I wish to recommend two very good talk by Herb Sutter; Machine Architecture: Things Your Programming Language Never Told You and Concur ad C++ Futures.
Friday, February 19, 2010
Unskilled and unaware of it
I just read the Unskilled and unaware of it post at Successful Software. It's a good post that (should) make you think about how good you consider yourself in various fields such as software development and driving.
I find it a bit funny that there are some skills that you probably don't overestimate your own skill level. Have you ever heard of someone saying he/she is a great gardener when in fact every flower they touch die?
Update: See Dunning-Kruger effect on Wikipedia.
I find it a bit funny that there are some skills that you probably don't overestimate your own skill level. Have you ever heard of someone saying he/she is a great gardener when in fact every flower they touch die?
Update: See Dunning-Kruger effect on Wikipedia.
Monday, January 25, 2010
Detecting function inlining
By definition, compiler optimizations should only affect the performance of the application. The behavior of the optimized code should be the same as the non-optimized code. If this is the case, how is it possible to detect whether a function has been inlined or not? Dear reader, read on (that's what readers do, right?).
We compile the code and run the tests. There is a green light. Everything is good. We commit the code to the repository.
Before we continue, let's take a step back and ask ourselves why it would ever be useful to detect function inlining. Let's take an example. Imagine the following code is part of a large application developed at company where we pair program. The function createObject() allocates an object on the stack (that is, it's a local variable) and returns a pointer to it:
int function() {
Object* o = createObject();
return o->field;
}although it's bad practice to return a pointer to a local variable, function works and does precisely what you'd expect: it creates an object and returns one of its fields. As developers with good taste, we decide to clean up the code a bit by introducing a getter for field:
int function() {
Object* o = createObject();
return o->getField();
}Not so fast! After a while the automated build system indicates a whole lot of failing tests. What happend?
Here's what happend: since we introduced a function call to getField we changed how the stack looks when reading the field field. And since the object is stack allocated, the object is overwritten by the call to getField. Good team players as we are, we do not want to have failing builds for long, so we revert our last check-in and start to inspect the problem closer.
We quickly determine that the only failing builds were the non-release builds, that is, those builds that failed were those that did not optimize the code. We stare into the air and ask ourselves... why?
At this point one of us remembers a blog he had read the night before about function inlining. He explains "if the call to createObject is inlined into function, then the object is allocated as a local variable in function instead of in createObject. This means that when getField is called, the object is not overwritten. It's not overwritten because its allocated in a different place on the stack. In a different stack frame, to more precise."
The other developer thinks about this for a few seconds and replies "ok, then let's just allocate the object on the heap instead of the stack". Before the blog-reading developer can say "memory leak" he adds "and, of course, delete it when we're done with it".
After a few minutes of coding and half an hour of waiting for the compiler to finish, we have a working solution that works on both optimized builds and on non-optimized builds. We commit the code and leave for the day.
When we get back the morning after, we have an angry mail in out inbox. Apparently our little fix made the performance of the application degrade horrendously -- we had placed a call to new inside an extremely tight loop. Doh! Stupid us. A better solution is needed. In order to understand the problem properly the pair programmers summarize:
- For optimized builds the function is inlined, thus stack allocation work fine. With stack allocation the performance of the application is acceptable.
- On non-optimized builds the function is not inlined, thus stack allocation does not work and we have to resort to heap allocation. However, heap allocation is not acceptable for performance.
When the problem is so clearly stated, the blog-reading developer exclaims "let's allocate on the stack if the function is inlined, and allocate on the heap otherwise!"
Ok, now let's leave those two developers, I think they can handle it by themselves now. I'm now going to explain how to do the trick the blog-reading developer suggested.
For every function that is called there is a stack frame which contains the function's local variables. Every stack frame has an address, which can be accessed via a register called EBP (extended base pointer, I think). This register can be read using the following code:
void* stack_frame() {
register void* ebp asm("ebp");
return ebp;
}This function returns the pointer to the stack frame that is created when entering the function. So, as you can see, it's really simple to get the pointer to the current stack frame. Let's make another function and provide it with the pointer the stack frame of its caller:
bool is_inlined(void* callers_ebp) {
register void* my_ebp asm("ebp");
return my_ebp == callers_ebp;
}This function is kind of magic because it will return true if its inlined and false otherwise. Using this we can write a function that allocates on the stack if the function is inlined, and allocates on the heap otherwise:
Object* createObject(void* callers_ebp) {
register void* my_ebp asm("ebp");
if (my_ebp == callers_ebp)
return &Object();
else
return new Object();
}Pretty sweet.
Note that the EBP register is not used when compiling with -O2 or -O3 unless you use -fno-omit-frame-pointer. It should be possible to do the same trick without EPB by using the ESP register instead, but I haven't tested that.
(Disclaimer: I'm not suggesting that this is a good way for solving the problem the two developers in the story faced. What I do say it that in those rare circumstances when the behavior of a function need to change when its inlined, then this is one way to do it.)
Etiketter:
C,
C++,
crazy stuff,
memory management,
optimizing,
pair-programming,
stack
Subscribe to:
Posts (Atom)