Writing

Feed Software, technology, sysadmin war stories, and more.

Thursday, March 28, 2013

Fat frameworks and itty bitty mobile machines

It's funny how things seem to invert themselves when you go from the world of desktop computing to mobile devices or vice-versa. I encountered this firsthand the other day while chatting with a friend who is a master app hacker. He had just sliced through a wicked bug and wished to tell me about it.

It seems his program blew up when running on certain devices. It was hitting a memory limit which existed on some of the smaller models, and the kernel was shutting him down. He managed to instrument it to see where the memory would spike and then slowly work its way back down to prior levels. It was concurrent with a fetch from his backend server.

He started poking around. This fetch was essentially a call into some system library which said "hey, go get this URL for me". Unfortunately, that library decided to go off and bring in the whole thing as fast as it could. All of this happened inside his app's address space, so the buffer grew and grew. Then it would hit the limit and the OOM-killer would go off. Oh, the embarrassment.

His fix involved twiddling some knobs which made it not try to chew nearly as much memory with buffers. This got rid of the spike, and the program no longer died on that particular kind of device. This made everyone very happy, and there was much rejoicing.

Upon hearing this, I realized how strange it was. He's running on a device which is limited in terms of CPU speed, RAM, and even flash storage. There's also a battery to worry about, and to make matters even more interesting, you might find yourself running on a slow cellular link from time to time. On this system where you have to be very careful about using the minimum set of resources at all times, the APIs are thick and heavy. They tend to put you at a great distance from the things like TCP sockets way down under everything.

Then, at the same time, there's the state of programming for desktop machines. I have this stupidly large Linux box here for running my software defined radio stuff. It has something like an 8-way CPU, several gigabytes of memory, hundreds of gigabytes of disk space, and an always-on Ethernet connection to a pretty fast cable modem pipe. It also has all the juice it can need by virtue of being plugged into the wall at all times. There is no battery to worry about.

On this machine, you really don't have to worry about saving CPU cycles, memory, disk space, bandwidth, or battery runtime. You can go all-out and just waste things outright if you want. So, what sort of programming happens on this box? Well, most of it is plain old C and C++, or pretty close to the bare metal. There aren't multiple layers of APIs between me and a network socket, for instance.

Isn't that strange? The itty bitty "boxes" with limited resources have these relatively fat frameworks happening on them while the monster boxes have people running extremely close to the bare metal.

Sure, there are reasons for why things are like this, but it's always interesting to take a step or two back now and then. Sometimes, you'll see a situation which really might not make sense to an outsider. Seriously. Try explaining the "slow machine + fat framework" and "fast machine + lean code" thing to a non-programmer. They'll probably think we're all nuts.

Who knows. Maybe they're right.