Archive for January, 2008

Moral Instinct

Steven Pinker wrote an interesting article in the New York Times magazine this Sunday. I’m not a big Pinker fan. I think he tends to simplify a little too much, and sometimes falls into the classic error of evolutionary psychology: thinking that a plausible explanation is the right explanation. This was a good article, though, discussing research on what our instinctive moral judgements might be. As I’ve written before, I think that it is an interesting possible grounding for a universal ethics. In fact, I don’t know of a better one.

I’m not going to discuss the whole article, which you can read for yourself, but I’m going to pick out one quote: “In the West, we believe that in business and government, fairness should trump community and try to root out nepotism and cronyism. In other parts of the world this is incomprehensible — what heartless creep would favor a perfect stranger over his own brother?” The point is not, in fact, expressed fairly: we do not expect people to favor perfect strangers, we expect them to recuse themselves to avoid conflicts. Since people often fail to recuse themselves, we threaten them with punishment to force them to do so.

The real point is that we enforce the idea that the interests of society take precedence over personal interests. Some other societies (apparently) do not. Where did this idea come from historically? How many societies adopt it? Can we make an argument for it based on any sort of moral instinct, or must we argue for it based on beneficial results?

OK, I’m going to mention one more point. Pinker suggests that some people dislike research into moral instinct, on the grounds that finding a natural basis for morality will discredit the more philosophical basis. I would be more sympathetic to that argument if we had any grounds to believ that we will in fact find a more philosophical basis, one which is not grounded on an argument from the authority of God.

Comments (24)

NPG

Population growth must stop. Regardless of what we believe the resource limit of the planet is, it is clear that there is a limit. If population growth continues, we will hit that limit. As the saying goes, anything which can not go on forever will stop.

Fortunately, the rate of growth of population is slowing. The major factors appear to be increasing wealth, increasing education of women, and increasing access to birth control.

However, some powerful organizations, such as the Catholic Church, are opposed to the use of birth control. Clearly not everybody believes this–even many Catholics must use birth control. However, I’m also sure that many people do believe it. It follows that the slowing rate of population growth will itself stop at some point, when it hits the limit of people who believe that birth control is immoral.

Therefore, it is essential for our long-term pleasant existence on this planet that the Catholic Church, and other organizations opposed to birth control, change their position. Fortunately, there is historical precedent for this. At one time most, perhaps all, Christian churches forbade birth control. However, they have changed their position. For example, at the seventh Lambeth Conference, the Anglican Church agreed that birth control could be used. The Catholic Church has reversed themselves in the past. We must hope that they will do so again on this issue in the relatively near future.

Comments (4)

Article about Books about Iraq

A depressing article about some books about Iraq, written by soldiers and a journalist who were there during the initial invasion. Of course war has huge human costs, but it’s hard to be unmoved by these stories about a war of choice. And it’s very hard to reconcile them with our goals and our inability to control the country after the invasion. It will be very interesting to see in twenty years how many Iraqis will feel that the invasion was a good thing–I’m sure there will be quite a few, but I wonder what percentage. And it will be interesting to see how long it takes the U.S. to forget how badly it went, and how long it will take to get involved in another foreign adventure.

Comments

Fermi Forge

I recently reread Greg Bear’s SF novel The Forge of God, after coming across it in a book. It’s a novel about the destruction of the Earth. I may be too pessimistic, but I find it to be one of the most convincing explanations of the Fermi paradox.

Assuming our civilization doesn’t collapse, it’s going to become very easy for us to send machines across the whole galaxy in a time which is small compared to the lifetime of the universe. It’s going to be so easy that it will inevitably be done by some person, somewhere. The chances that we are the only intelligent life in the galaxy seem to be me to be, literally, astronomically low. So: where are the machines created by other intelligent life?

Bear’s book gives one answer, essentially an update of Saberhagen’s Berserkers: there are machines out there which destroy worlds. The book describes the Earth as a lamb calling out into a dark night, unaware of the wolves closing in. I hope that’s not the universe we live in, but I can’t think of a likelier explanation. I can think of many other possible explanations, I just can’t think of a likelier one.

This is not, of course, refuted by the ongoing failure of SETI. It’s clear that we will soon stop broadcasting radio ourselves. After a hundred years it won’t make any sense to even set up a beacon. So it seems to me that SETI is based on a false premise conditioned by our current technology. It’s still worth spending some time on, of course, just in case.

In the meantime, I hope that our civilization stays out of the Malthusian trap long enough to find out where everybody else is, or whether we truly are alone.

Comments

Signed Overflow

The C and C++ language standards say that overflow of a signed value is undefined behaviour. In the C99 standard this is in section 6.5. In the C++98 standard it is in section 5 [expr], paragraph 5. This means that a correct C/C++ program must never generate signed overflow when computing an expression. It also means that a compiler may assume that a program will never generated signed overflow.

gcc has taken advantage of this fact for a long time when optimizing. For example, consider this function:

int f(int x) { return 0×7ffffff0 < x && x + 32 < 0x7fffffff; }

If signed arithmetic simply wraps on overflow, then this is equivalent to 0×7ffffff0 < x, since adding 32 to such a value will yield a negative number. However, even gcc 2.95.3, released in 2001, will optimize this function into code which simply returns 0. This is valid because the compiler may assume that signed overflow does not occur in a correct program, and getting a negative number from x + 32 can only happen from signed overflow.

Recently gcc has started using undefined signed overflow to implement better bounds tests. In particular, consider code like this:

int f()
{
int i;
int j = 0;
for (i = 1; i > 0; i += i)
++j;
return j;
}

This code is assuming that if it keeps doubling a positive number, it will eventually get a negative number. That is, it expects signed overflow to behave in a certain way. Current mainline gcc will see that the signed overflow can not occur in a correct program, and will compile this code into an infinite loop.

Some gcc users were surprised by this optimization, and there was an outcry around the beginning of 2007. For a while there was a suggestion that gcc compilations should always use the -fwrapv option. -fwrapv tells the compiler to treat signed overflow as wrapping. That is how Java defines signed overflow. The option was introduced in 2003 for gcc 3.3.

The disadvantage of -fwrapv is that it inhibits optimizations. Most programs do not produce signed overflow, and, as we have seen, no correct programs do. The compiler can generate better code when it can assume that signed overflow can not occur. This particularly arises in loops. When a loop uses a signed integer index, the compiler can do much better when it doesn’t have to consider the possibility that the index will overflow.

Consider this trivial example:

int f(int i) { int j, k = 0; for (j = i; j < i + 10; ++j) ++k; return k; }

What does this function return? When the compiler can assume that signed overflow is undefined, this function is compiled into code which simply returns 10. With the -fwrapv option, the code is not so simple,, since i might happen to have a value like 0×7ffffff8 which will overflow during the loop. While this is a trivial example, it is clear that loops like this occur in real code all the time.

However, gcc does need to respond to the concerns of the user community. I introduced two new options in gcc 4.2. The first is -fno-strict-overflow. This tells the compiler that it may not assume that signed overflow is undefined. The second is -Wstrict-overflow. This tells the compiler to warn about cases where it is using the fact that signed overflow is undefined to implement an optimization. With these options it is possible to detect cases where signed overflow occurs in a program, and it is possible to disable optimizations which rely on signed overflow until the program is fixed. The -Wstrict-overflow warning even found one minor case where gcc itself relied on wrapping signed overflow, in the handling of division by the constant 0×80000000.

This naturally leads to the question: what is the difference between -fwrapv and -fno-strict-overflow? There is a clear difference on a processor which does not use ordinary twos-complement arithmetic: -fwrapv requires twos-complement overflow, and -fno-strict-overflow does not. However, no such processor is in common use today. In practice, I think that the code generated by the two options will always behave the same. However, they affect the optimizers differently. For example, this code

int f(int x) { return (x + 0×7fffffff) * 2; }

is compiled differently with -fwrapv and -fno-strict-overflow. The difference occurs because -fwrapv precisely specifies how the overflow should behave. -fno-strict-overflow merely says that the compiler should not optimize away the overflow. With the current compiler, with -fwrapv (and -O2 -fomit-frame-pointer), I see this:

movl $1, %eax
subl 4(%esp), %eax
addl %eax, %eax
negl %eax
ret

With -fno-strict-overflow I see this:

movl 4(%esp), %eax
leal -2(%eax,%eax), %eax
ret

Same result, different algorithm.

Comments (6)

« Previous entries · Next entries »