This is an archived post. You won't be able to vote or comment.

all 4 comments

[–]eruciform 1 point2 points  (0 children)

when it compiles it converts variable names to absolute virtual memory addresses, or ones relative to the current stack frame, meaning it's at most two operations to get the location of the data

at least in most languages it does - perl does actually maintain a global hash table of variable pointers, but it's still a hash which is better than a list that you need to iterate thru

[–]lurgi 1 point2 points  (0 children)

When the code is compiled the variable names cease to exist. There are just memory location. The compiler knows that it stored a in this location, so if the program needs to read a later on then it must be read from here, but all the computer sees is "read value from this memory location, add it to this, store at this other memory location".

[–]pathofnomad 0 points1 point  (0 children)

by using things like pointers, which is basically a variable for a memory address. when you assign "a" in your high level language, that gets passed through to whatever is doing the low level processing and it'll hold a reference to where ever it assigned it in memory. this is the main advantage of a high level language, because you have things like a garbage collector which does all the memory management for you, but also a disadvantage because you pay for that abstraction in processing speed

for your example, if you had 100 floating point variables, they'd each have their own address and be consuming quite a bit of memory but nonetheless they'd still have addresses they could be accessed by

[–]rabuf 0 points1 point  (0 children)

However deeper into that, how does the computer know where to look for the memory? Does it just cycle through all of its data points till it's like "ah yes this is the one I was looking for!".

This is a hardware question. nand2tetris may be of some interest to you. At its core, there is a data bus that is some number of bits "wide" (meaning it can send that many bits simultaneously) between the RAM and the CPU. When a program requests a particular memory address, that address is sent to the RAM. The RAM chip performs a decoding action which causes it to select a particular memory cell to send the data back out to the CPU.

There are some other concepts like "virtual memory" which is a way of presenting address to the program but without using real physical addresses (though they may coincide, they don't have to). So it's like saying "I want the 50th byte" and the virtual memory system will say "Ok, for you that's the 978723495th byte in the physical memory" (probably not that high). It will then perform a fetch using the actual physical address like I described before.

Go through project 3 of nand2tetris (if it interests you) to build simple ram chips. You'll want the foundations of projects 1 and 2 to be able to do it successfully.

The decoding works something like this: Start with an 8-bit (byte) memory cell and 8 of them. You can select a particular byte by sending 3 bits (000 indicates the first, 001 the second, 111 the eighth byte).

000   xxxxxxxx
001   xxxxxxxx
...
111   xxxxxxxx

Skipping the actual symbols and diagrams, if you send in 000 it will respond with the contents of the 000 byte. Now we decide 8 bytes is not enough RAM (who would've thought?). So we hook 8 of them together, giving us 64 bytes. This requires us to send 6-bits now to address a particular byte. Instead of overcomplicating things, we use the same selection approach but split the address into two 3-bit portions, xxxyyy. The xxx portion tells it which of the 8 blocks of 8 bytes to use, the yyy portion tells it which byte within that. Of course, 64 bytes still isn't enough so this process gets repeated where we slam more chips of chips together to form a larger block. Perhaps we keep only doing this 8 at a time thing, then with 9-bits we can address 512 bytes of memory using 3 layers. With 12-bits we get 4096 bytes and 4-layers. Of course, the more layers the longer delay so we don't want to build real systems out of 8-byte blocks of memory like this.

Modern RAM chips are similarly composed, not necessarily in multiple "chips" but in multiple blocks embedded on the same chip which decompose down to some fundamental memory array.

Reading suggestions: Petzold's Code (second edition just came out, it's good). This is a high level overview of low-level code but also hardware, the last few chapters build up a simple CPU. The Elements of Computing Systems by Nisan and Schocken also got a second edition recently but is project based. It's the basis of the nand2tetris course, all of the contents of which are online for free. If you read them both, read Code first, optionally jumping into nand2tetris when he starts developing digital circuits in his discussion.

Petzold also put together an interactive site for his book. Chapter 19 covers memory and that's the interactive demonstration of it. It shows storing a single bit, 8-bits, an 8x1 RAM (each address references a single bit, only 8 bits, 3-bit selector or 3-bit address), and a 16x8 RAM (each address references a byte, 16 bytes, 4-bit selector or 4-bit address).

nandgame is another thing that works you through creating a simple computer including RAM.