tags:

views:

303

answers:

11

It recently occurred to me that I (and I think most people) learned computer programming starting with something like Visual Basic. I began to wonder if we had started at the lower level first if it would be easier now.

Do you think it is any value as a programmer to understand things like how a CPU works, the basic instructions, and things like that? I mean after all aren't we really talking to it in the end?

If we started at the CPU level and taught from there up we might find that we can understand how to manipulate it at a high level easier.

+11  A: 

It goes both ways.

For example, a lot of people that started at a higher level have no idea why shifts are so much faster than multiplication and division, or the impact of branching, etc.

As a result, they often write code that is slower, but easier for the average person to understand. (Note that for some applications, going faster is more important than being easy to understand)

Someone that has an understanding of what's going on behind the scenes (how many clock cycles different operations take, how a CPU's pipeline works, the impact of caching, etc) can often write code that is very fast, but can be difficult for many people to understand/maintain. (This is particularly difficult in applications where the "optimization" has no perceivable benefit, and maintainability is more important)

Personally I feel that knowing "what's going on below" at least gives me the ability to know the impact of the decisions I'm making.

Honestly, at this point, I don't mind leaving a lot of the low level details/optimizations up to the compiler. It probably does a better job than I would anyway :]

Daniel LeCheminant
+1  A: 

Higher level languages are meant to abstract us from the lower-level architecture of the system we're working on. While this doesn't mean that architectural information should be ignored, it does mean that the value of this information is diminished. Architecture specific knowledge can indeed help you to leverage the system in different ways, but usually these ways include bypassing the abstractions our high level languages provide for us. Whether this is a good thing or not I leave to you.

Erik Forbes
+2  A: 

There is still a community of programmers who did learn that way.

There's no debate in my mind that having an awareness of the hardware that you're working with can give you great insights into how to best to write your code for that hardware. Having said that, some of the most hardware-specific code I've encountered (and written) has also been the least readable and maintainable.

I think that for programming in general, it's not hugely important. However, once you get into performance critical areas, it's a key skill to have.

dominic hamon
+1  A: 

This is one of those questions where there is no one answer.

Practically, no, there is not much use for that, unless you're doing something very specific (in which case you would have given a much more specific question).

Theoretically, and this is an argument which everyone opposing will use, yes, it is always good to know (... pretty much everything) ... until it comes down to programming with only ones and zeros :)

If you started at the lowest level, you would have probably never gotten up to this 'high' level - this is exactly the reason why 'high level' languages were written in the first place.

ldigas
+2  A: 

I think an appreciation of the underlying architecture is useful for any programmer, and that too much abstraction can be a bad thing.

I don't know if working up from the low level is a good idea, as modern CPUs are very complex - I learned Visual Basic followed by Java, but am so glad I learned C and some assembly languages afterwords, as it helped me to write performance critical code.

Tarski
+5  A: 

I've learned quite a bit about low-level programming, and I think it's been tremendously helpful in every bit of code I write. Even high-level languages have some version of, say, the basic synchronization primitives (mutexes/locks, conditions, semaphores); they still have to read from the disk or from a network card; they still have to copy bytes from one place in memory to another, and so on... the point is, the fact that you're using a high-level language doesn't mean it's useless to know how those things work. If you have an understanding of how a computer functions at the lowest level, you can always apply that knowledge to write more efficient and/or less bug-prone code regardless of how abstracted your platform is. Knowledge of the low-level operations can even teach you things that you might never have learned otherwise - there's no better way to learn how to properly use something like a mutex than to have to implement one. (Okay, maybe that's slightly exaggerated, but you get my point I hope)

Bottom line, I would say that yes, it is absolutely a good idea for programmers at all levels of abstraction to learn about the fundamentals. But I don't think it's necessarily such a good idea to start with the fundamentals. Programs at the level of assembly language are notoriously hard to understand and I think trying to foist that on a beginner to programming is just likely to discourage him/her. I mentioned that understanding basic operations will help you write more efficient and/or less error-prone code, but it's certainly not necessary to write code at all. So in my opinion, most people would probably do best starting somewhere in the middle, where they can still latch on to familiar concepts like objects while getting acquainted with the process of coding. After some experience in that area, CPU stuff is fair game ;-)

David Zaslavsky
+1  A: 

"If we started at the CPU level and taught from there up we might find that we can understand how to manipulate it at a high level easier."

False.

I started programming in the 70's where you absolutely had to know how the hardware worked because your choices were Fortran (or Jovial) vs. assembler.

Now I use Java and Python on -- well -- I have really no idea. I have a Dell Laptop, a MacBook, an iMac and a server that I can't positively identify.

These could have Intel or PowerPC processors or -- well -- I think the server is 64-bit, but I don't know which kind.

Knowing a lot (a real lot) about some processors didn't help. Knowing nothing about modern processors doesn't hinder.

Software captures knowledge. A specific piece of hardware has little to do with the knowledge captured by software.

S.Lott
+1  A: 

It gave me more confidence about what I was doing and gave me knowledge about when to focus on performance or maintainability (in almost 99% of situations i choose the last one :)

Diones
+4  A: 

I expect my doctor to know how my heart works (but not necessarily be able to perform heart surgery), I expect my mechanic to know how my engine works (but not necessarily be able to build an engine), and I expect my programmer to know how the CPU works (but not necessarily be able to build a CPU, or write an enterprise app in assembly. However, a discussion of CPU cache or seeing some assembly code should not send him running for the hills either).

We are professionals. We are expected to know how things work "under the hood," even if we don't normally work at that level.

Giovanni Galbo
I like that statement: "We are professionals."
Craig S
+1  A: 

I started programming in Basic (on paper tape!), but one of the best experiences in my early career was to work in embedded systems, writing C and assembly language programs, and often cross-compiling. Knowing what the hardware does, how the higher level language maps to the CPU, and so on is very helpful. It certainly helps you understand pointers, pointer arithmentic, data structure alignment, sign extension, and even software performance and operating system behavior when you understand the hardware to some degree.

Craig S
+1  A: 

Programming languages are virtual machines. C, C#, Fortran, Basic, etc are CPUs in and of itself, albeit portable. They say that if you are programming on Fortran, you are programming on some sort of Fortran machine. If you are programming on C, you are programming on some sort of C machine. There's even a language implemented on hardware-level, LISP.

There's even a joke on C. The C Programming Language : A language which combines all the elegance and power of assembly language with all the readability and maintainability of assembly language.

You can reach every nooks and crannies of pointers, manual memory manipulation, instructions, pointers to function, etc with languages like C, or C# with unsafe option.

You are not missing something even if you don't know the CPU in depth.

But if you really want to squeeze performance out of your program, there's a real value in knowing what goes under the hood, learn the CPU/assembly language if the program merits it.

Hao