Archive for the ‘General’ Category

System 76 Lemur Ultra

Thursday, December 6th, 2012

On one of my recent work trips, my venerable IBM Thinkpad T42 finally gave up the ghost.  Even if it hadn’t failed on me, I was reaching the point where I wanted more out of my laptop.  Having the thing die the day before a demo certainly forced the issue, though.

I generally run free operating systems on my machines, including my laptops.  My desktops have been FreeBSD since I migrated from an Amiga 3000 in the early 1990s.  So, yeah, I’m one of those guys.  Laptops are a particular pain in this regard.  There always seems to be something that isn’t quite supported or that you have to tweak to get working.  Even with the T42, I wound up running Ubuntu rather than FreeBSD.  Love FreeBSD though I do, I like to be able to suspend – and the Linux install hibernated, too.

I had bought the T42 from Overstock.com on the theory that an older machine would be well supported.  That was true as far as it went, but older hardware does mean fewer capabilities, Rather than pick another machine that was older in the hope that the OS support would be seamless, I decided to get something more modern from a company that packaged Linux on the machines.  I suppose Dell or someone like that would also load Linux, but I would much rather support a company that supports Linux at a more grassroots level.  I poked around and decided to buy a Lemur Ultra from System 76.

The Lemur had the right mix of small size and power that I wanted.  Well it did after I upgraded to 4-core i7.  The availability and  pricing of that option lured me away from ZaReason.  I probably could have gotten equivalent hardware a little cheaper, but the price was definitely competitive. And I looked forward to a laptop where things worked out of the box.

Buying was painless, and even though I ordered the weekend before Thanksgiving, things shipped on a reasonable schedule.  They claim 5-8 business days to ship, and they certainly got it out within that time.  They also sent e-mails as the order progressed.  Not enough to annoy, but enough that I knew it was coming.  In fact, I got it the day they shipped it.  That’s one of the joys of living in SoCal, I guess.

The Lemur arrived in box-in-box packaging, with no real frills.  Ok a little frill; here’s the inner box:

Inner box

My cat took them up on the offer:

Jackson and the Box

(OK, that’s the outer box…)

Everything was well protected, but not excessively over-packaged.   Excess packaging is something we like to avoid when we can in my house, and this was all reasonable.  The contents were just what I ordered.  A laptop, a power supply, and a single paper pointing to the System 76 web site and Ubuntu docs was all that was inside.  (And 2 “Powered by Ubuntu” stickers.)

That's it...

Plug in the power brick and hit the on button, and the laptop jumps into the Ubuntu install process.  That process  is very straightforward and user friendly, and I’ve been through it a couple times.  I imagine even a complete newcomer to Linux would find it a pretty pleasant experience.

install screen

After finishing the install, things just worked.  That was a welcome change from the usual hours or days of fiddling with settings, tweaking the BIOS, or finding or modifying drivers.  Now I could fiddle to get the machine comfortable.

The Hardware

Overall I’m very pleased with the Lemur hardware.  I chose the T42 after getting sick of lugging a heavier Dell model around.   The T42 was small and solid feeling.  The Lemur is a little bigger, but feels lighter.  The materials feel thinner, somehow, but I have no indication as yet that they are any less durable.  I’ll follow up in a couple months when I’ve had more experience.

While the laptop itself is lighter, the power supply is a brick in every sense.  Upgrading to the i7 means upgrading to the 90W power supply, and any weight savings from the machine is eaten up by the brick.  Now, that’s hard to complain about.  This box has more than 4 times the processing power of the T42, and every indication is that the battery lasts twice as long, which I both like and asked for.  And the power supply itself is longer and sturdier looking.  But I wish I had a lightweight option.

Another thing I liked about the lemur was its keyboard.  The IBM Thinkpads are tough to beat for keyboard feel, but the Lemur’s keyboard is decent.  The keys have a nice travel, and feel like keys, not chicklets or buttons.  Unlike the larger System 76 laptops there is no keypad, but I don’t miss that in a laptop.  The trackpad merges seamlessly with the wrist rest.  There is literally no seam, which is pretty neat.

keyboard and trackpad

The trackpad supports edge scrolling or two-finger scrolling.  I prefer the two-finger, but am happier that both work.

One of the Lemur’s extended function keys toggles the trackpad on and off.  I haven’t had to use it, except figuring out what it does.  (I actually thought I’d broken something until I realized what the somewhat obscure symbol meant.)  The other extended function keys also work seamlessly, which is a simple thing, but much appreciated.  The only complaint I have about the controls is that there is no LED to indicate that the integrated webcam is on or off.  (There’s nothing indicating that for Bluetooth, either, but I don’t use that feature much at all).  I also miss the thinklight, but no reasonable person could condemn a machine for not having one.

The other hardware just works. Both the wireless networking and the ethernet port do exactly what they should when activated – even when used together.  The Intel 5000 graphics adapter works without tweaks, and the 720p screen looks good running Unity and playing DVDs.

DVD

I’m sure I’ll test the real performance of the system more in the coming months, but initial indications are that it does everything I need it to do.

I haven’t done an exhaustive test on the battery life.  I have had the laptop disconnected for a couple hours at a time in meetings at work, and the system projects something in excess of 3.5 hours of life doing meeting kinds of things.  Again, this is something I’ll get a better feel for as I use it in more strenuous conditions.

Overall, after only having the Lemur a couple weeks, I’m very pleased with it.  I’m enjoying tweaking Ubuntu and spending time working on and playing with the machine.  Based on this short experience, I’d recommend System 76 and the Lemur.  Check back in a couple months and we’ll see how it’s going.

Playing with Go: a concurrent quicksort

Thursday, May 31st, 2012

A little while ago google released a concurrent programming language called go that appeals to my curiosity as both an academic and a guy who likes to write code. I road tested it by coding up a concurrent quicksort implementation.  This summarizes my generally positive impressions of the language.

Go appeals to me as an academic because it supports the CSP concurrency model.  CSP, introduced in a paper by  C. A. R.  Hoare,  is a programming system that supports concurrent threads that interact primarily by sending synchronous messages.  The synchronous messages are unusual in that a message is never in flight.  Sender and receiver have to both stop to exchange the data, so a message exchange is a combination of synchronization – like acquiring a lock – and data exchange.  In order to  put more concurrency into a system where both parties to a data exchange have to synchronize, CSP introduces non-determinism to some language constructs involvoing communication requests.  A programmer can say “I’ve got three messages to send out. If any of the receivers is ready, send to them, and if more than one is ready I have no preference for which message you send.”

This combination encourages designers to think in unusual ways and it’s a fun paper to expose students to.  I’ve often wanted to sit down and code up some algorithm in CSP and see how well the model really works.  Go is probably the highest profile CSP-ish implementation, so it’s attractive.  I say CSP-ish because it keeps the spirit of the paper but extends the ideas in practical ways – communication channels are made independent of thread names and allow multiple threads to communicate on a channel; non-determinism is extended to both reading and writing; things like that.

Before I talk about Go, I’m going to review quicksort and how to make it concurrent.

Quicksort

Quicksort is a fast sorting algorithm that is amenable to concurrent implementation.  Until I sat down to write this, it hadn’t occurred to me that the quicksort was also created by C. A. R. Hoare. What that means –  other than Hoare is a smart guy – I don’t know, but I have a sudden desire to try to work monitors in here as well.

Quicksort is based on the clever observation that one can sort an array by partitioning the elements around a pivot element and then doing the same to each of the partitions.  The partitioning step consists of picking an pivot element in the array, p,  and moving the elements in the array around so that all the elements less than p have indices less than p and vice versa.  Partitioning will usually move several array elements, including p, around.   Notice that the partitioning has put p into the place it belongs in the array – no element will ever move from the set that’s smaller than p to the set that’s larger; once a partitioning step is complete, its pivot element is in its sorted position.

The diagram below illustrates partitioning on a small array of 5 integers (1 through 5).  The two arrows indicate the range of the array to partition (the whole array) and the pivot element is in green.  We arbitrarily pick the first element as the pivot here.  The array on top is the array before partition, and the one on the bottom (below the dotted line) is the partitioned array.

partition

Partition Step

Quicksort is a recursive algorithm – an algorithm that repeats the same procedure on sub-problems to get the answer.  Once the partitioning step is completed, the process starts over again on the two sub-arrays on either side of the pivot element.  The pivot element is in the right place, so it is in neither sub-array.  A partition step on a one-element array or a zero element array returns immediately, without partitioning the sub-arrays.  The figure below shows the complete sorting of our 5 element array using quicksort.

callgraph

One worker sorts an array

Time goes from top to bottom of that diagram, so the final, sorted array is the bottom array (on the right).  Each dotted line is a partition step, and each pair of solid lines is the recursive step of partitioning the sub-arrays.  Each partition step is carried out on the sub-array defined by the arrows that touch the array at that step.  The single thread of control follows the blue arrow.

The quicksort algorithm has been studied a lot and is the basis of most in-memory sort routines.  It is also amenable to a concurrent implementation.  Each step in the recursion – each time the partitioning routing is called – operates on an independent subarray.  That’s the observation that leads directly to a concurrent implementation, as we’ll see below.

Concurrent Quicksort

My simple concurrent implementation – and I’m sure I’m not the first to do it – uses  a collection of worker threads and a coordinator thread.  The coordinator sends a message to an idle worker telling it to sort the array and waits to receive messages from the workers about the progress of the algorithm.

A worker partitions a sub-array, and every time that worker gets ready to call the partition routine on a smaller array, it checks to see if there is an idle worker to assign the work to.  If so, it sends a message to the worker to start working on the sub-problem; if not the current worker makes calls the partition routine itself. 

After each partitioning, two recursive calls are (usually) made, so there are plenty of chances to start other workers.  The diagram below shows two workers sorting the same 5-element array. Each blue line represents the flow of control of a worker thread, and the red arrow represents the message sent from one worker to start the other. (Since the workers proceed working concurrently, it is no longer guaranteed that the smaller elements in the array will be ordered before the larger; what is certain is that the two workers will never try to manipulate the same elements.)

calgraph2

Two workers sort an array

A worker can complete working either because it has directly completed all the work sorting the subarray it was initially called on, or because it has ordered a subset of that array but has passed some or all of the remaining work to other workers.  In either case, it reports the number of elements it has ordered back to the coordinator.  (The number of elements a worker has ordered is the number of partitions of sub-arrays that have 1 or more members).

When the coordinator hears that all the elements in the array have been ordered, it tells the workers that there is nothing left to do, and the workers exit.

That’s the basic idea.  In the code attached, I incorporated some common optimizations to the quicksort algorithm, but the basic idea is that at every step where a worker might call the quicksort routine on a smaller sub-array, it passes that job to another worker if a worker is idle.

So, how do we do that in Go?

Implementing in Go

The whole commented package, including test code, is available. I’m only going to talk about the parts of it that coordinate the multiple workers traversing and sorting the array. Most of the code snippets below are directly from the package, and the one that is not is a minor simplification.

I’m not going to go into great detail about Go syntax here. The language specification, other references, and tutorials at http://golang.org are quite good.

My implementation is wrapped in a class that keeps the sorting parameters together. It holds the channels for communicating between the coordinator and the workers, and between workers, as well as the number of workers to start. In addition, when a sub-array is small enough, my implementation stops using the recursive quicksort algorithm and does a simple insertion sort to finish the job; the size of “small enough” is also stored in the class instance. The data structure that holds these looks like:

// Parameters that hold across the sort
type SortContext struct {
    workers int
    lim int
    work chan *Chunk
    done chan int
}

The number of workers to start is in workers, an integer. If a sub-array has fewer than lim elements (an integer), insertion sort is used. Idle workers listen on work, a channel that carries pointers to chunks of work; a nil Chunk means that the worker can terminate. When a worker completes a chunk of work it sends the number of array elements it put in order to the coordinator on the done channel, which carries integers. The number ordered is the number of recursive quicksort calls plus the number of elements passed to insertion sort.

Starting a worker thread in Go is as simple as prepending the go keyword to a function call.  Starting a set of workers is as simple as:

// Start up a set of workers
for i := 0; i < self.workers; i++ {
    go self.worker()
}

Each of those workers has access to the channels through the enclosing class structure. That loop is how the coordinator starts a concurrent sort.

The worker routine looks like this:

func (self *SortContext) worker() {
    for c := range self.work {
        if c == nil { break }
        self.done <- self.p_qsort(c.a , c.l, c.u)
    }
}

The worker loops, assigning each chunk it reads from the work channel to the c variable as it gets the chunks. If the chunk is a null pointer (nil) the worker breaks out of the loop and exits. Otherwise it calls the parallel quicksort function (p_qsort) with the array to sort and the bounds (c.l is the lower bound and c.u is the upper). That function returns the number of elements it directly ordered, which the worker sends to the done channel, and waits for the next chunk.

That’s fairly terse code, but pretty clear and idiomatic after a surprisingly short time. Of particular note is the for var := range channel idiom, which reads messages on a channel until the sender closes it. This code explicitly exits the loop because there are many potential senders on that channel; each worker may send on it, so no worker closes it.

Multiple workers can execute that loop without interfering with each other’s ability to read messages from the channel. If more than one worker is blocked on self.work and a worker sends a message on it, exactly one of the blocked workers will receive the message. There is no guarantee which, of course.

That construct makes it simple to start as many or as few workers as the environment dictates.

After starting the workers, the coordinator does this:

// Deliver the work to the first worker who listens
self.work <- &Chunk{a, 0, a.Len()}

That chunk of work is to sort the array called a from its first element to its last element. The array a (really a slice for you Go sticklers) is a parameter to the member function that started the sort.

Making that call blocks the coordinator until a worker starts listening for a chunk of work. As soon as one blocks to receive a chunk, that first chunk is delivered, the worker starts working and the coordinator moves on to:

// Count up the ordered elements
for i:=0 ; i < sz; {
    i += <-self.done
}

The coordinator waits for each worker to report completion of each chunk of work it does. When the whole array is sorted (sz is set to the total elements in the array), that loop terminates and the coordinator shuts down the workers by sending them all a nil chunk of work.

// Tell the workers to terminate
for i := 0; i < self.workers; i++ {
    self.work <- nil
}

The only thing left to sketch is how workers start other workers. After each partition step, a worker has (at most) 2 sub-arrays that need to be partitioned. For each subp-array this worker does the following (where l and u are the lower and upper bound of the subarray to be partitioned):

select {
    case self.work <- &Chunk{a, l, u}:
    default:
        rv += self.p_qsort(a, l, u)
}

The select statement will send the message (self.work <- &Chunk... ) if there is a worker listening on self.work. If not, the code will choose the default branch, which is a recursive call on self.p_qsort.

A couple details: The case: self.work ... line is guarding an empty block after the colon. If statements followed it, they would be executed after the message was successfully sent. No such additional statements are required here. In the default: branch, the rv += ... adds the number of elements ordered by the recursive call to the number ordered so far in this call. This routine will return rv to the caller and eventually to the coordinator. You can see how that works in the complete code.

The select is actually slightly simplified from the running code, which includes another bypass used when the insertion sort is invoked. Again, see the complete code.

This use of select is a particularly convenient construction. It is short enough that converting the recursion in the serial version to the choice of recursing or starting a worker in the concurrent version does not interrupt the flow of the code.

More importantly, it is encoding a fairly sophisticated concurrent operation – “hand this work off if there is an idle worker, but do it in this worker if not” – succinctly and idiomatically. One can perform the operation in conventionally threaded languages, like java, but each programmer generally rolls their own mechanism to implement it. That extra activation energy often gets the better of programmers. Go encodes the construction so simply that one hopes programmers will use it more often.

Seeing For Yourself

The code includes a couple benchmarks that can show that this implementation does take advantage of multiple processors.  To run it, install the source in your GOPATH and compare

$ go test -test none -bench '.*' psort
$ go test -cpu 4 -test none -bench '.*' psort

On my 4-core i5 the results look like:

$ go test -cpu 1 -bench .\* -run none psort
PASS
BenchmarkOneWorker 1 4176997000 ns/op
BenchmarkFourWorkers 1 4104459000 ns/op
BenchmarkTenWorkers 1 4220084000 ns/op
ok psort 12.655s
$ go test -cpu 4 -bench .\* -run none psort
PASS
BenchmarkOneWorker-4 1 4165567000 ns/op
BenchmarkFourWorkers-4 1 1633784000 ns/op
BenchmarkTenWorkers-4 1 1632001000 ns/op
ok psort 7.526s

Each of these benchmarks sorts 5 million integers. That’s one “op.” The BenchmarkOneWorker benchmark uses one worker thread and takes about 4.2 seconds to sort the array; BenchmarkFourWorkers uses 4 workers and BenchmarkTenWorkers uses 10.

In the first invocation, with -cpu 1, only uses one CPU, so no matter how many workers are used, there is no speedup. In the second invocation, with -cpu 4, adding workers adds CPUs, so there is an appreciable speedup, though not completely linear.

Feel free to play around with it or use it in projects, but there are corner cases where it will perform badly.

Closing Remarks

Overall I was pleased with the concurrency support.  It did take some time, but the language and features do lead a programmer toward efficient abstractions. 

The documentation often repeats the phrase “communicating for concurrency” which is an excellent guiding principle for getting the most out of Go.  I went down a couple blind alleys when I tried to do other things, like start as many goroutines as possible without communicating between them, or letting many messages pile up in buffered channels hoping that a goroutine would finally get around to reading them.  Neither of those works as well as sending a message when an idle worker is listening, which is the direction Go pushes you.

2010 Books

Friday, December 31st, 2010

I just posted my last capsule reviews for 2010, and looked back at the list of books I read this year.  I read 44 books this year, less than one a week, but still a fairly healthy number.  And it doesn’t count comics.

I wanted to pick a few that were particularly good and say a few words about them, but that’s proving to be hard.  I read a lot of really great books this year. I’m going to throw out a few links to some of the stuff I enjoyed the most.

In non fiction, this was the year I was blown away by Kevin Roose’s incredible The Unlikely Disciple, found out a ton about the recent Wall Street shenanigans in Michael Lewis’s excellent The Big Short, saw how a serial killer and the World’s Fair danced an abstract tango in Erik Larson’s The Devil in the White City, heard a rational plea for coming to terms with our finite planet from Jared Diamond in Collapse, and became a Chuck Klosterman fan by Eating the Dinosaur.

I read more fiction than usual this year.  Partially this was because I discovered Raymond Chandler (The Big Sleep, The Long Goodbye, and Farewell, My Lovely) and renewed my interest in Dick (The Man in the High Castle and A Scanner Darkly) and Atwood (The Year of the Flood, Oryx and Crake, and The Handmaid’s Tale).  I also got sucked into the Twilight thing, knocking off all four constituent books in pretty short order.  I also finally read The Grapes of Wrath, which is a towering work of literature, and found Lionel Shriver’s spectacular We Need to Talk About Kevin, a harrowing mirror held up to both the reader and the world.

That’s a pretty good year by my standards, and there are other fun things that didn’t quite make a mention here.

Review: The Iliad

Saturday, November 13th, 2010

This is a translation of The Iliad by Edward Earl of Darby in 1862, unsurprisingly free for the kindle, my current e-book reader of choice. I’d read parts of The Iliad in high school and had been meaning to get back to it.  Things come up, however, and twenty some-odd years later I finally got around to it.

I thoroughly enjoyed the reading it, front to back.  I suspect that I would have enjoyed it less in high school, but now it was an endless parade of delights.

First of all, it’s a rip-roaring Hollywood blockbuster of a story.  It’s one bloody encounter after another, described vividly and in detail.  I tried to read Mallory’s Le Morte d’Arthur a few years ago and found it deadly dull.  A big part of the reason for that was how sterile and ethereal all the interactions and altercations were.  Sure Arthur “slew on the left and slew on the right” but that leaves it all pretty vague what was going on.  With Homer You Are There: he describes the various movements of the heroes and how they face each other to the point of telling where the victorious spear enters the loser’s body and just how the body came apart.  While I do not feel any great need to know that Hector decapitated someone as opposed to disemboweling them, the overall tone is much more detailed and close to the action.  As a result the characters and situations are more lively.  Mallory seemed like literature to me in the worst pretentious way; Homer feels like a story that gets retold and amplified by people.

The translation is also a source of fun.  I can imagine a very direct translation that tries to get the meaning across as clearly as possible to modern readers so that they can easily follow events from a couple thousand years ago. That’s not what the Earl provides at all.  Apparently he’s trying to capture the flavor of the ancient Greek, and not knowing any Greek I can’t tell how he did.  What I can say is that his translation has a quirky rhythm and flow all its own.  For example, evidently negation was an intensifier in ancient Greek, because no divine intervention takes place without at least three offsetting negations: “you should not hesitate to avoid throwing your spear.”  It’s all comprehensible, but just alien enough to remind you that Homer’s world is a different place.  It’s also all pretty consistent, which gives the text the flavor of a stylist rather than a translator.

I also enjoy the little shout-outs and digressions throughout that remind the reader that this was a history of the war and the warriors and communities that contributed to it.  It is pretty common to introduce a character and describe his history and personality in the space between a spear being thrown at him and dashing out his brains.  Longer digressions describing the founding of cities or the lineage of the heroes also pop up.  While all this diverts from the main plot, I find it charming that some Greek soldier otherwise lost to the mists of time gets a brief moment of immortality here.

So, overall, The Iliad is a lot of fun to read, and it certainly helps your literacy in the classics.

Strongly Recommended.

Killing the Ivy

Saturday, May 15th, 2010

If you’ve met me in real life, you’ve probably heard me complain about the ivy that’s been overgrowing my house for a while.  I let it go long enough that killing it was going to be a major undertaking.  This week Brenda and I found someone to undertake it.  Here are some pictures of the piles of ivy after most of it was pulled.

We’re really happy to be taking this first step to relandscaping the place.

Upgrade to WordPress 2.8.6

Friday, November 20th, 2009

Auto upgrade to 2.8.6 today. That was slick.

Server upgrade for Ylum

Sunday, October 11th, 2009

Today I finally finished the latest hardware upgrade to ylum, the server you’re probably reading this on.  I’ve been trying to upgrade it in one form or another for a month or a month and a half.  The original goal was to get a FreeBSD gmirror running for backups (along with filesystem snapshots for file recovery).  That required upgrading my hardware because the old cheap motherboard I was using wouldn’t support the SATA disks I was moving to for mirroring.  Then I had another bad bargain basement experience, and a second motherboard with transient lockup problems.  All in all frustrating.

This weekend I stopped by Fry’s and picked up an Intel motherboard and Intel i5 4-core CPU.  Gotta dig the matching boxes:

Matching Boxes

Matching Boxes

The only problem is that I didn’t realize that this board has no parallel ATA controller until I was standing there with nowhere to plug my old disk in.  I was able to use the unreliable motherboard to move my data and OS over to a SATA disk, which just booted and ran on the Intel motherboard.  Not an upgrade path I would recommend, but overall things are pretty good.  FreeBSD doesn’t quite see the onboard ethernet yet, but that should be a minor problem, and I have a legacy PCI ethernet in there now that’s doing fine.  The new ylum internals look like this:

Ylum innards

Ylum innards

There’s some cleanup and tweaking to do, but 4 2.66 Ghz CPUs make software updates fo much faster.  And mirroring should go into use shortly.

Sorry for any inconvenience, and as always we thank you for your support.

One more review

Monday, August 31st, 2009

I forgot to review Super Folks last night. That review is up on Bell Book and Candle now as well.

Into the Longbox

Thursday, January 29th, 2009

Will Eisner’s The Spirit #25, Aragones, Evanier, Amancio, Barta. Another reasonably diverting Spirit story. I do get a kick out of Amancio’s anatomy. There hasn’t been any unpardonable gaffe for a while, but occasionally his enthusiasm for the female form makes for some unrealistic depictions. Not the usual Power Girl overendowment problems, but some parts do appear to be glued on for effect. It says a lot about the goodwill I’ve built up for the writers that I’m letting that slide.

Doktor Sleepless #11, Ellis, Rodriguez. More of our walk around Heavenside after a few months of Dr. Sleepless stirring the pot. Or really plopping some ingredients into the pot and watching it work, I suppose. I can’t see a new reader jumping in here, but there are plenty of things to notice for the folks already playing along at home.

Sandman: The Dream Hunters #3, Gaiman and Russell. Russell’s adaptation of Gaiman’s classic Sandman story continues to showcase his beautiful draftsmanship and poignant storytelling. There are long lyrical sections where Russell leads us along through the plot without need of words, and exquisite panels where the composition of the frame and figures adds as much to the text as the expressively rendered faces. A master class in comic art.

Secret Six #5, Simone, Scott, Hazlewood. And on the other side of the intellectual spectrum, Simone and company’s wild ride through the DC universe with the villains continues. On the one hand, this is a pure action thriller; on the other hand, it’s remarkably well executed. It’s been a long time since I’ve enjoyed the ride in a mainstream comic this much, much less gasped at a last page reveal. This is great genre comics. (Actually, it’s great comics, but if you’re not into the underwear perverts, the costumes and genre conventions may prevent your suspension of disbelief.)

Döner Kebab

Sunday, December 7th, 2008

Though I complain about it, there are many cool things about my job. One of those things is that it causes me to occasionally find myself in, say, Spain at 10:30 PM local time on a Sunday and starving after waking up from a jet-lag-induced crash. You may be looking for the good part, and so was I.

I went down to the front desk and asked about the food prospects. It’s Sunday in Madrid and I don’t speak the language. The desk clerk was not optimistic. A man’s gotta eat, so I’m off into the raining night.

I should mention parenthetically that not only is it raining, but I have no umbrella and no jacket; I’m dressed for Los Angeles. It’s nice to live in a place with only nice weather, but it does encourage one to forget to plan for the weather. My continuing inability to learn this lesson is a source of great amusement to my friends.

I walk 100 yards and there’s McDonald’s. It’s nice that I won’t starve, but eating at McDonald’s in Madrid seems to be admitting defeat. I’ll explore further before returning to the golden arches.

By this point, I’m actually getting into the adventure of looking for late night food. It’s always fun to wander around some part of a city that isn’t full of tourists. You get off the beaten path and get to see the people who live here going about their lives. Almost inevitably the most fun I have when traveling are those times.

So I’m pushing along through the cold and I pass a little something or other. I think they call them snack bars in France; it’s a little lunch counter kind of thing. It’s also packed to the gills, like a local bar on a Wisconsin football weekend. There’s a soccer match on. Now if I spoke any Spanish at all, I’d probably go for this, but I’m not excited at nodding and pointing at a bartender in a crowd to try to get a frozen pizza. It’s on the list above the McDonald’s, though, so things are looking up.

The landscape’s getting less promising, though. There are more apartments and small offices and fewer storefronts. There’s a closed bar – “Bar Chappeau” – and some restaurants that are wisely closed. And there’s some small nook that’s selling kebabs. I’m wondering whether this is worth a try, when I see the name of the place – Döner Kebab.

A week ago that wouldn’t have meant anything to me, but sometime in that week – it may have been this afternoon – I saw that name in my friend Phil’s IM status. Phil lives in Geneva, working for Google, and the sort of guy that I’m happy to follow into adventure. So if Döner Kebab is good enough for Phil, it’s good enough for me.

It was pretty much perfect. A made some half-assed attempt to order the special off the menu (and here you want to think sandwich shop menu), and failed miserably. I do not have wonderful pronunciation of languages I allegedly speak, much less ones I don’t. It wasn’t any great leap to figure out that I wasn’t from around here. But the fellow behind the counter replied to me in pretty good English that he was out of fries, but would be happy to cut me a deal on a kebab and a drink. He made the food while conversing with a few folks who were obviously regulars, and I watched Spanish TV on a grainy set and took in the atmosphere.

The kebab was fair. Nothing very tasty, but I was pretty hungry. While I was eating a few more customers came through, including a Japanese woman who was even more lost than I was. He flirted with her a bit and got her on her way with a late night meal. I paid up, and we chatted for a few minutes about the US economy. No, really. This is the kind of small joint magic I love.

Anyway, that’s how the Internet made my life better today. A small association nudged me into a vibrant Spanish slice of life.