Do you have any interest in effectively using a debugger? Then yes. Do you have any interest in writing reliable or efficient code? Then yes.
Personally I care about the backend more than the frontend. I recommend compiling for ARM instead of x86, in this case you are not learning assembler necessarily (where I recommend writing your own disassembler), so if you use gcc it has a disassembler and you can see what both your high level code does to change the end result, as well as how much change you can make with compiler options. It is an eye opening experience for most high level language programmers to realize that the same code can have wildly different results based on the compiler and command line options used.
For the middle of the compiler I recommend both lcc and sdcc. You may or may not want to buy the lcc book:
[http://www.cs.princeton.edu/software/lcc/][1]
You dont need to though, the source is on the net (in many forms). As is sdcc (small device c compiler, created originally for the 8051 and other 8 bit micros). My recommendation there is to go into the interface where the compiler meets the backend, you will find that your code has been turned into a series of atomic parts, sometimes reverse polish like. a = b + 7; might end up being load the constant integer 7. read from memory the variable b into the next available registers. Add 7 plus the register with b and save in the next available register. store the value in register to the location in memory for a.
You can do this with gcc as well, but you may end up realizing that gcc isnt as great as you though it was. Because of the number of languages and number of backends and number of hands in the mix, etc, it is huge and complicated. It does get by though, and does work for the languages and platforms that have experts maintaining. What gcc may teach you that the others cannot is that, the various languages on the frontend will boil down into a common middle language that the back end turns into specific instructions for each platform.
Lastly the frontend. For the most part folks use bison/yacc, which is a tool that you create a description for your high level language and the tool can parse the user input based on your description and turn it into this middle language if you will.
If you plan on your hobby or career having to do with writing software I would say you must go through this exercise once if not many times. The overall quality of your code, the reliability of your code, the performance of your code, and the efficiency writing code will be affected by this knowledge.
I would be careful with the statement "don't write for the compiler, but write for people to read." There is a lot of bad code out there because that kind of statement is misused. Writing code for maintainability results in bad code that has to be maintained. Maintainability is mutually exclusive with reliability and performance. I would personally have reliability and performance than bad code that any college grad can maintain.
You will learn, over time, not to try too hard to write for the compiler. Just dont be wasteful with your code, dont use gee whiz features of the language. If you had to do extra research in order to figure out some compiler feature, you can be sure that most of the world doesnt understand it including the person who is supposed to implement it in the compilers. Therefore you can expect that feature to not work consistently across compilers, therefore you should use it in the first place. This also means dont try to write your code for one specific compiler, dont get too attached to gcc and its features, try sdcc and lcc and microsoft and borland and kiel and others. Make your code clean, simple, readable, and portable.
Bottom line, if you are serious about writing software, then you absolutely need to know how the compiler works. gcc, sdcc, lcc, (and vbcc if you can find it) are all free, open source, and provide a learning experience that will improve your coding skills.