« April 2007 | Main | June 2007 »

May 2007 Archives

May 2, 2007

Atomic Incrementing

I found a great quote:

Locks are like tanks - powerful, slow, safe, expensive, and prone to getting you stuck.

It goes well with this picture:

Creating atomic increments (and avoiding locks) on various architectures is absurdly difficult harder than it should be. And portable? HA! You said “portable.” I’ve been looking into it, and here’s my little collection of implementations.

So, there’s a small amount of information out there about doing it on PowerPC. In GCC’s inline-assembly, on Linux (using gcc 4.1.2) it looks like this:

void atomic_incr(int * operand, int incr)
{
    asm volatile (
        "loop:\n\t" /* repeat until this succeeds */
        "lwarx  6,0,%0\n\t" /* reserve the operand */
        "add    6,6,%1\n\t" /* add incr to it */
        "stwcx. 6,0,%0\n\t" /* put the sum back, and release it */
        "bne- loop" /* start-over on failure */
        :
        : "r" (operand), "r" (incr)
        : "r6"
     );
}

For some idiotic reason, this is different on MacOS X:

void atomic_incr(int * operand, int incr)
{
    asm volatile (
        "loop:\n" /* repeat until this succeeds */
        "lwarx  r6,0,%0\n\t" /* reserve the operand */
        "add    r6,r6,%1\n\t" /* add incr to it */
        "stwcx. r6,0,%0\n\t" /* put the sum back, and release it */
        "bne- loop\n" /* start-over on failure */
        :
        : "r" (operand), "r" (incr)
        : "r6"
     );
}

Note the addition of r’s in front of all of the register numbers.

But that’s just fine. It makes some sense, and above all: it works!

Actually, here’s an even better one (more optimizable, and more cross-platform):

void atomic_incr(int * operand, int incr)
{
    register tmp;
    asm volatile (
        "loop:\n" /* repeat until this succeeds */
        "lwarx  %2,0,%0\n\t" /* reserve the operand */
        "add    %2,%2,%1\n\t" /* add incr to it */
        "stwcx. %2,0,%0\n\t" /* put the sum back, and release it */
        "bne- loop\n" /* start-over on failure */
        :: "r" (operand), "r" (incr), "r" (tmp)
     );
}

Now, show me the same thing for Intel processors. What’s that? You can’t? Of course not. Because Intel loves mucking with this stuff, so each of their processors uses a slightly different syntax to get the best speed. That, and getting it into GCC syntax is additionally difficult because some genius keeps changing the GCC assembler semantics.

Here’s a basic atomic increment that works on most x86 machines (NOT i386’s):

void atomic_add(int * operand, int incr)
{
    asm volatile (
        "lock xaddl %1, %0\n" // add incr to operand
        : // no output
        : "m" (*operand), "r" (incr)
    );
}

It uses xaddl so that I don’t have to worry about output, and can do the memory operation. The following also works, but may not be as fast (or it may be equivalent):

void atomic_add(int * operand, int incr)
{
    asm volatile (
        "lock xaddl %1, (%0)\n" // add incr to operand
        : // no output
        : "r" (operand), "r" (incr)
    );
}

Here’s a version that works on 386’s. I don’t know which is “faster” on all architectures:

void atomic_add(int * operand, int incr)
{
    asm volatile (
        "lock addl %1, %0\n" // add incr to operand
        : "=m" (*operand)
        : "r" (incr), "m" (*operand)
    );
}

But does ANY of that work on fancy Itanium (ia64) machines? Hell no!

You may be wondering: how does the Linux kernel implement atomic increments on ia64 machines. Like this:

#define atomic_add(i,v) \
({ \
    int __ia64_aar_i = (i); \
    (__builtin_constant_p(i) \
     && (   (__ia64_aar_i   1) || (__ia64_aar_i    4) \
         || (__ia64_aar_i   8) || (__ia64_aar_i   16) \
         || (__ia64_aar_i  -1) || (__ia64_aar_i   -4) \
         || (__ia64_aar_i  -8) || (__ia64_aar_i  -16) \
            ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \
            : ia64_atomic_add(__ia64_aar_i, v); \
})

Yeah, pretty sweet, no? Separate functions for doing simple math versus doing other increments. Here’s a simple increment:

void atomic_oneup(int * operand)
{
    uint64_t res; // this MUST be 64 bits
    asm volatile (
        "fetchadd4.rel %0=%1,%2"
        : "=r" (res)
        : "m" (*operand), "i" (1)
        : "memory"
    );
}

Note that it HAS to return something, because it’s a fetch instruction. But it’s also conveniently atomic. And that increment doesn’t have to be 1, obviously, but could be any of the ones listed in that ugly #define. But what about adding arbitrary numbers? For this we must use cmpxchg. Here’s how Linux uses it (tidied up a LOT):

static __inline int ia64_atomic_add (int i, atomic_t *v)
{
    __s32 old, new;
    do {
        old = atomic_read(v);
        new = old + i;
    } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old);
    return new;
}

How can you not love something like that? Boiling it down, that call to ia64_cmpxchg turns into: ia64_cmpxchg4_acq((__u16*)v, new, o); (that o variable is a place-holder). THAT, in turn, is this:

#define ia64_cmpxchg4_acq(ptr, new, old) \
({
    __u64 ia64_intri_res;
    asm volatile ("mov ar.ccv=%0;;" :: "rO" (old));
    asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv":
    "=r" (ia64_intri_res) : "r"(ptr), "r"(new) : "memory");
    ia64_intri_res;
})

Just so we don’t go insane here, here’s a condensed loop:

void atomic_incr(int * operand, int incr)
{
    int64_t res, old, new;
    do {
        old = *operand; // atomic if operand is 32-bit aligned
        new = old + incr;
        asm volatile ("mov ar.ccv=%0;;" :: "rO" (old));
        // these are separate because the compiler inserts stuff in between
        asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv":
                    "=r" (res) : "r"(operand), "r"(new) : "memory");
    } while (res != old); // if res==old, our computation is out of date
}

Ugly much? Just a bit.

Something else I’ve discovered, which is kinda critical. There is a big difference between

asm volatile ( /* stuff */ );

and

asm __volatile__ ( /* stuff */ );

Which is that gcc is MUCH more careful not to muck with the latter, but feels free to modify the former if it feels it would be a good idea. The only difference between

asm volatile ( /* stuff */ );

and

__asm__ volatile ( /* stuff */ );

is that the latter can be used if the former conflicts with something.)

May 13, 2007

Bible Puzzlers

Under the category of “things that puzzle me”, I submit the following:

“Not everyone who says to me, ‘Lord, Lord,’ shall enter the kingdom of heaven, but he who does the will of my Father who is in heaven. On that day many will say to me ‘Lord, Lord, did we not prophesy in your name, and cast out demons in your name, and do many mighty works in your name?’ And then will I declare to them, ‘I never knew you; depart from me, you evildoers.’

That’s Matthew 7:21-23 (NAB). Pretty straightforward, right? And it makes sense in that it agrees with other parts of the bible: just mouthing the words isn’t enough. Right?

But wait, not so fast! Acts 2:21 (NAB) quotes (kinda) the prophet Joel, and says:

And it shall be that whoever calls on the name of the Lord shall be saved.’

That was Peter, standing and announcing this to the men of Judea. But, what should we make of this? Is mouthing the words enough? Hmmm, well, let’s refer to what he’s quoting. Joel said in Joel 2:32 (or 3:5 in the NAB):

I will restore to you the years which the swarming locust has eaten, the hopper, the destroyer, and the cutter, my great army, which I sent among you. “You shall eat in plenty and be satisfied, and praise the name of the LORD your God, who has dealt wondrously with you. And my people shall never again be put to shame. You shall know that I am in the midst of Israel, and that I, the LORD, am your God and there is none else. And my people shall never again be put to shame. “And it shall come to pass afterward, that I will pour out my spirit on all flesh; your sons and your daughters shall prophesy, your old men shall dream dreams, and your young men shall see visions. Even upon the menservants and maidservants in those days, I will pour out my spirit. “And I will give portents in the heavens and on the earth, blood and fire and columns of smoke. The sun shall be turned to darkness, and the moon to blood, before the great and terrible day of the LORD comes. And it shall come to pass that all who call upon the name of the Lord shall be delivered; for in Mount Zion and in Jerusalem there shall be those who escape, as the Lord has said, and among the survivors shall be those whom the Lord calls.

So, what’s the context here? Well, Joel was talking about an invasion of locusts that the Lord saved the Israelites from. Technically, He had commanded the invasion in the first place, so you can view it as “God called off the attack dogs” (er, “attack locusts”). Hrm. That doesn’t help. So, what’s Peter bringing this locust invasion up for? The apostles were just imbued with the gift of tongues, and everyone in Jerusalem could understand them in his own language for the first time, so Peter stood up, seized this momentous occasion under inspiration of the Holy Spirit, and this was the first thing he said:

Men of Judea and all who dwell in Jerusalem, let this be known to you, and give ear to my words. For these men are not drunk, as you suppose, since it is only the third hour of the day; but this is what was spoken by the prophet Joel:

“And in the last days it shall be, God declares, that I will pour out my Spirit upon all flesh, and your sons and your daughters shall prophesy, and your young men shall see visions, and your old men shall dream dreams; yea, and on my manservants and my maidservants in those days I will pour out my Spirit; and they shall prophesy. And I will show wonders in the heaven above and signs on the earth beneath, blood, and fire, and vapor of smoke; the sun shall be turned into darkness and the moon into blood, before the day of the Lord comes, the great and manifest day. And it shall be that whoever calls on the name of the Lord shall be saved.

Well, that doesn’t really help so much either. Peter is explaining that they’re speaking in tongues by quoting Joel’s prophesy about the end of days. In essence, he’s saying that these are the last days, and this (the fact that everyone can understand them in their own language) is a result of God pouring out His Spirit. So, whoever calls on the name of the Lord during these days (i.e. now) will be saved, but for the people BEFORE Jesus’s time (i.e. before the last days) calling on His name wasn’t enough? … I don’t know. That doesn’t sound reasonable. This is why it puzzles me.

Update (11/17/08): Something to consider is that “Lord” isn’t God’s name, it’s His title. Thus, saying “Lord, Lord” is calling upon the Lord’s title. A bit nitpicky, perhaps, but that does technically resolve the logic of the statements.

Here’s another one. In Acts 15 (RSV), the Bible talks about the big controversy over whether or not the Gentiles must necessarily be circumcised. Peter decides that they do not need to be circumcised, and so they send an open letter to the Judeans, that reads:

This is the letter delivered by them: “The apostles and the presbyters, your brothers, to the brothers in Antioch, Syria, and Cilicia of Gentile origin: greetings. Since we have heard that some of our number (who went out) without any mandate from us have upset you with their teachings and disturbed your peace of mind, we have with one accord decided to choose representatives and to send them to you along with our beloved Barnabas and Paul, who have dedicated their lives to the name of our Lord Jesus Christ. So we are sending Judas and Silas who will also convey this same message by word of mouth: ‘It is the decision of the holy Spirit and of us not to place on you any burden beyond these necessities, namely, to abstain from meat sacrificed to idols, from blood, from meats of strangled animals, and from unlawful marriage. If you keep free of these, you will be doing what is right. Farewell.’

That’s it? That’s the whole of it? None of this “love no god before me” or “love thy neighbor” or “love each other as I have loved you” business? They boil the entirety of Christ’s commands down to abstaining from meat and unlawful marriage?!? What about Christ’s statement, quoted in Mark 7:18-19 (NAB):

And he said to them, “Then are you also without understanding? Do you not see that whatever goes into a man from outside cannot defile him, since it enters, not his heart but his stomach, and so passes on?”

What on earth was the point of the list the apostles put into that letter? … I haven’t a clue.

Now, different translations of the Bible translate that last sentence a little differently. What I quoted above was from the NAB (New American Bible). But the RSV (Revised Standard Edition) translates that last sentence as:

If you keep yourselves from these, you will do well.

That’s a bit different, eh? One is brotherly advice, one is the definition of the difference between right and wrong. Still, what’s the point of that list? They didn’t specifically say “you can skip circumcision”; as best I can tell, the point is just that circumcision is left off of that list. But then, trying not to murder anyone is ALSO not on that list. If they aren’t defining something important (right from wrong, say, where things left off the list are just as important as what’s on the list), then the list is really rather pointless and is significant only in that it has nothing at all to do with circumcision. If it IS defining something important, then… aren’t a few details missing? I am befuddled.

But, I did find a quote that’s better than Timothy’s on deeds and faith. John 14:23-24 (NAB):

Jesus answered him, “If a man loves me, he will keep my word, and my Father will love him, and we will come to him and make our home with him. He who does not love me does not keep my words; and the word which you hear is not mine but the Father’s who sent me.

That, at least, is not so puzzling.

May 22, 2007

Alice

My Dad recently pointed me to this article about the programming tool, Alice. Essentially, the idea is that the way to address the attrition of students away from Computer Science is to make learning programming more “fun.” To that end, Alice provides a Sims-like graphical interface that allows you to express basic programming control flow (iteration, conditionals, etc.) without needing to worry about things like syntax, memory, variables, or math.

I think it’s an interesting idea. I don’t really agree with it, but it is interesting. I mean, I can see a stronger argument for starting with Lego Mindstorms than starting with this thing. Why must computers be reduced to telling stories about three little pigs in order to get anyone interested? Math doesn’t have to do that. Physics doesn’t have to do that. Biology doesn’t have to do that. The Alice author makes fun of adding 20 numbers together, but come on; in calculus, you spend months trying to understand (and memorize) trigonometric equivalents and logarithmic estimations so that you can finally use derivatives to calculate the volume of an imaginary, physically impossible, three-dimensional shape. To mockingly quote him, “Hu-freakin’-rrah.” You have to start somewhere.

If the benefit is primarily that you can easily visualize your algorithms, I would counter that Logo (where you program a “turtle” (triangle) to draw lines) did the same thing back in the 80’s.

And I’m shocked by the vocabulary of this program (Alice). The most popular OS programming language, C, has 32 keywords. Alice, apparently, has 10,000. And it’s supposedly easier?

It’s a shame the author of the article spends so little time pondering the all-important question “Are students who use Alice actually learning what they need to learn?” My own objections to it aside, that’s the really important question.

Though I do feel that when you take your homework home, it shouldn’t look like you’ve been preparing class materials for a kindergarten teacher unless that’s what you have been doing. I mean, what’s next, teaching computers with sock puppets? Perhaps we can get a magician in? And hey, if we can somehow involve gluing glitter and uncooked pasta to things, so much the better, right?

… I may be going a bit overboard there, but seriously. There’s a time and place for infantilizing the subject matter. College-level computer science courses are not it. If there’s a place for Alice, I’d say it’s probably in middle-school. (SOMEthing has to take the place of HyperCard.)

I agree with Jane Robbins (one of the commenters) when she says “The goal isn’t to fill the enrollments, is it? That’s a bad basis for making curricular decisions.”

About May 2007

This page contains all entries posted to Kyle in May 2007. They are listed from oldest to newest.

April 2007 is the previous archive.

June 2007 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.34