| Welcome to Mp2d. We hope you enjoy your visit. You're currently viewing our forum as a guest. This means you are limited to certain areas of the board and there are some features you can't use. If you join our community, you'll be able to access member-only sections, and use many member-only features such as customizing your profile, sending personal messages, and voting in polls. Registration is simple, fast, and completely free. Join our community! If you're already a member please log in to your account to access all of our features: |
| Learning | |
|---|---|
| Tweet Topic Started: Mar 20 2008, 04:08 PM (1,354 Views) | |
| PY | Sep 21 2008, 11:11 AM Post #46 |
![]()
Banned
![]()
|
that is amazing tim. .4GB of ram is what I eat for breakfast, however. I have twice that free, and am playing crysis. |
| <img src='http://notpy.notstaticfire.co.uk/Hurr I am plane.png' border='0' alt='user posted image'> | |
![]() |
|
| Timmeh | Sep 29 2008, 05:32 PM Post #47 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
So now I'm learning how to code for SNES, in 65816 assembly. I don't think anyone here actually wants to get involved, but I'm so fascinated by the differences between assembly and higher level languages that I think I'm going to post a brief overview of the coolness. DISCLAIMER: I don't know shit. If I'm wrong, D: and :[. I'm working under the assumption that none of you will ever write a single line of assembly in your lives, so any inaccuracies in what I say don't really matter. Anyway, yeah, let's... commence. The first and fascinatingest thing ever is that the code of assembly seems to translate directly into binary. You can code it in binary if you so prefer. An example line of code looks like this:
This SAME code looks like this in machine code:
(note: this isn't an SNES command, it's for intel processors) In contrast, C++ has no 1 to 1 correspondence between code and language. What's so cool about this? ALL compiled binaries (that you know and love by the name of .exe) can be written in machine code without any loss of data. Pretty darn awesome! (It also means writing compilers for machine code is stupidly easy...) The next point is the obvious point that it's very low level, meaning that when you do something, you are actually doing it. In a high-level language like TrueBASIC, when you assign a variable, you are actually cutting out an enormous chunk of memory, jamming numbers in there, making a separate piece of memory that holds the variable's name, making a variable that stores the location of the variable, and suchlike. In C++, a medium-level language, when you assign a variable, you are requesting memory, assigning a value to an address, an address to an address, and tying an address to a name. In assembly, you don't even have variables. You just have addresses and values. You can request memory. You can assign assign a value to an address. You can assign an address to an address. You can form a variable using the separate commands for doing those. Anywho! On to the way it works. Most all of the basics revolve around 3 things: 1) There are certain memory addresses that are responsible for stuff. For instance, the memory address at the 8448th location (commonly known as $2100, where $ means hexadecimal) is responsible for turning drawing on or off, as well as brightness. So all you have to do is write something there, and the computer automatically interprets it as meaning whatever it's supposed to mean. 2) There are 3 "registers", which I can't really describe, except as variables. Basically, they are your only 3 variables. EVERYTHING has to be done through them. For instance, you can't write a number to an address. You can write a number to a register, and you can write a register to an address.
The first line writes the binary value 00001111 to register A (the only register that can store values - the other two, X and Y, store addresses), and the second one writes the value in register A to $2100. These two lines turn the screen on and set it to max brightness. So, to reinforce the point, I'm not writing 00001111 directly to $2100, I'm writing it to A, and then writing A to $2100. 3) The code is stored in a linear order on the hard drive. The processor literally just reads it from the beginning to the end. Since the only looping and if statementing methods involve goto/label structures, this makes everything makes substantially more sense than in a higher level language. The code can easily be seen as a series of 1's and 0's and a jumping cursor flying over and reading it. Very very VERY logical and precise. There you have it. The awesomeness of assembly. Super nifty, amirite? |
| |
![]() |
|
| PY | Sep 29 2008, 06:12 PM Post #48 |
![]()
Banned
![]()
|
I think there's an emacs command for that. |
| <img src='http://notpy.notstaticfire.co.uk/Hurr I am plane.png' border='0' alt='user posted image'> | |
![]() |
|
| Timmeh | Sep 30 2008, 05:58 AM Post #49 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
1) rofl 2) I just realized PAIN: High level languages give errors if you mess anything up at all, even the minorest thing. Assembly frickin' NEVER gives errors (it's really hard to mess up lines of 3 letters and a number syntactically) but NEVER functions the way you want it to either. With great power comes great responsibility... |
| |
![]() |
|
| PY | Sep 30 2008, 03:30 PM Post #50 |
![]()
Banned
![]()
|
With great power, comes OH CRAP I WIPED MY RAM AGAIN |
| <img src='http://notpy.notstaticfire.co.uk/Hurr I am plane.png' border='0' alt='user posted image'> | |
![]() |
|
| Timmeh | Sep 30 2008, 06:36 PM Post #51 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
Precisely :/ |
| |
![]() |
|
| DeProgrammer | Sep 30 2008, 07:35 PM Post #52 |
|
Elite Pirate
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
By the way, your description of assembly was good. (I took an "introduction to microprocessors" college class a few semesters ago that taught me quite a bit about assembly and the inner workings of processors. I even got to program a processor by typing hexadecimal data on a little keypad.) |
![]() Signature by Rewrite. My talent comes from deep within...like vomit! | |
![]() |
|
| Timmeh | Oct 14 2008, 04:22 PM Post #53 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
So I made my first multithreaded program in response to the horsedickery in the Processors topic. And I must say, WOWZA. Without a pause in my code, moving a pixel 0.00000001 pixels a cycle throws it off the screen before I even draw to the screen. Without multithreading, it took a good minute at .0001 pixels a second. That's 10 thousand times faster! Here's why: For those of you who don't already know wtf multithreading is, it allows you to run different parts of a program independently of one another, each at its own pace. They still compete for processor time, but only as much as they compete with other processes. One doesn't strictly wait for the other (unless you tell it to for some reason). In the case of this program, I have two threads, one of which is responsible for calculations in real-time, and the other of which is responsible for displaying the results on the screen, which is ZOUNDS AND GADDLES more time-consuming than calculation, so if we do one calculation per every draw to the screen, we end up calculating ZOUNDS AND GADDLES slower. With multithreading, you can have one part go at the speed of your calculations, and the other at the speed of your drawing. |
| |
![]() |
|
| PY | Oct 14 2008, 04:37 PM Post #54 |
![]()
Banned
![]()
|
ZZZZZZZZZZZZZZOOM. |
| <img src='http://notpy.notstaticfire.co.uk/Hurr I am plane.png' border='0' alt='user posted image'> | |
![]() |
|
| Timmeh | May 25 2009, 06:23 AM Post #55 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
So it's been a while, but I'm writing a program now that should be vaguely interesting to some here, since it's gonna be doing some... *drumroll* RAYTRACING. In this case, the raytracing involved is astoundingly simple, since it involves a spherical light source of radius a centered at location (xl,yl,zl), a mirrored sphere of radius b centered at location (xs,ys,zs), and an observer of size 0 at infinity. Raytracing, as you probably know, just means that instead of assuming some things about the way light works, we actually take some light waves (not ALL light waves) and calculate the path they take through space. At this point I should inform you I lied to you - I'm not going to be looking at light waves (lines of light), I'm going to be looking at clumps of light waves that I know are reflecting off of one point on the sphere (cones of light). There's a good reason for this assumption though. The thing is that since I'm infinitely far away, infinitely zoomed in, and infinitely small, it's pretty hard to find light that actually intersects me (light that I can see). If a cone of light is pointed in my general direction, however, I know that I can see some of that light. Here's a picture of what I mean: ![]() Even though the observer is infinitely small and infinitely far away, some of that light is going to reach him. All I have to do to calculate if any given cone of light is reaching the observer is make sure that the sides of the cone pass on either side of the observer. TOMORROW (or whenever I get around to it): What cones of light are we talking about? EDIT: I didn't sleep, so here's the update where I talk about why the hell I think cones of light are relevant. Let's draw our system in two dimensions - a circular light source, a bigass shiny circle, and an infinitely small observer infinitely far away. ![]() The result we're looking for in the original problem is a 2D image - a 2D projection of the 3D sphere and the light reflected off of it. In this 2D case, our projection will be 1D. We want to form a 1D projection of the side of the 2D circle. The width of the circle is about 80 pixels, so what we're really looking to draw is 80 pixels of varying brightness. ![]() To me it seems the most logical way to calculate the brightness of each pixels, is to take another shortcut. Instead of tracking rays or cones of light emanating from the light source until we find one hitting the sphere at a point visible to the observer, we'll instead take a point visible to the observer (one of the 80 pixels), then check to see if there's any light shining on it at all, and finally we'll draw a cone of light from the source to the point on the circle in question. There's one tricky bit here - converting from a pixel to a point on a circle. This, actually, is the sole reason I chose to fix the observer infinitely far from the circle. This way, each pixel corresponds to a line in space, and all the lines are parallel and of equal width (1 pixel). Here's how that looks: Each of the black/white lines is a pixel in 1D space, and a point on the circle in 2D space. With that knowledge, all it takes is some basic trigonometry to translate each pixel into a point on the circle. Finally, we've advanced far enough to answer the initial question. Q: What cones? A: Each cone of light consisting of every ray emitted from the source and reflected off of the 80 points on the circle we're testing. ![]() The angle of the cone reflected is the same as the angle of the incoming cone. The size of the cones are the same too. We now know how to do all three steps involved in this raytracing system, at least in 2D space. Step 1: Pick a pixel on the 1D projection of the circle and convert it into a point in 2D space on the circumference of the circle. Step 2: Find the cone of light emanating from the source and hitting the point in question, and reflect it into space. Step 3: See if the reflected cone is visible by the observer. If the cone is visible, we can shade the original pixel in the color of the light source! That actually ended up covering all of the logic behind what I'm doing. I won't bother posting the math, because I'll post my code when I'm done if anyone wants to dig the math out, but maybe I'll make a post explaining the medium I'm working in (facebook graffiti) so that my code can be better understood when I do post it. I'll also probably post an explanation of how this is expanded to 3D space, even though it's really the same shit. PS The light involved here is perfectly reflected. If light is perfectly scattered (like on a sheet of paper - you'll never shine a light on paper and be unable to see it from a certain angle), then all you have to do is make the reflected cone infinitely wide... spherical, to be precise. The 'reflected' light goes in all directions. If you want to mix degrees of reflection and scattering, just make the reflected cone larger by whatever amount. The closer the size of the reflected cone to the size of the incident cone, the more reflective the surface will appear. PPS I haven't slept in 24 hours, please please please forgive me if I said anything stupid or wrong or overlooked something. I'm really tired. Goodnight! |
| |
![]() |
|
| Timmeh | May 29 2009, 05:23 AM Post #56 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
So I ran the first successful build of the code today and it um... didn't do anything. Please stand by >_> |
| |
![]() |
|
| Candy Man Criminal | May 29 2009, 02:56 PM Post #57 |
|
Metroid Prime
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
mayhaps you need to molest it for awhile? its usually works for me |
| |
![]() |
|
| DeProgrammer | May 29 2009, 07:24 PM Post #58 |
|
Elite Pirate
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
Incidentally, with your multithreading thing, the fastest speed increase you could get is (number of cores) * original speed. Did you not use a Semaphore or a Critical Section object to prevent the multiple threads from writing to the same variable at the same time? Because not using one of those can really screw up multi-threaded programs. Sure, sure, really old post, but what do I care? It's in this topic! <.< |
![]() Signature by Rewrite. My talent comes from deep within...like vomit! | |
![]() |
|
| Timmeh | May 29 2009, 08:25 PM Post #59 |
![]()
The Electryc Penys
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
The way I had the program set up, the speed increase was 1/10000 for the slower of two functions, and 10000 for the function that already took almost no time. Basically, the way I had it set up originally was a loop of two functions:
and then I put each function in each own thread:
What you're describing is if I'd gone from
to
The point is that the fast function is no longer limited by how slow the slow function is. So it can go as fast as it likes... and it happened to be about ten thousand times faster than the slow function. Yay! I forgot to mention, of course, that I'm not doing 10,000 times as much processing (that would be what increased by 2 times). But I am running a function 10,000 times faster. And to answer your question, no, I did not use a critical whatever, because I didn't write to the one variable the two threads shared at all in one of them, so there was no risk of doing that. |
| |
![]() |
|
| « Previous Topic · General Discussion · Next Topic » |











![]](http://z1.ifrm.com/static/1/pip_r.png)






2:31 PM Jul 11