Back from UDS-Q

Me at UDS

I’m back from from the Ubuntu Developer’s Summit for Quantal Quetzal (12.10)! This was my first UDS, and it was really cool to see so many developers from everywhere come together to make the next version of Ubuntu something amazing. I saw a lot of cool presentations, sessions, and talks. I also got a bit of sightseeing in in Oakland, San Francisco, and Berkeley on the weekend and at night.

Although I mostly went for planning the next version of the Ubuntu desktop interface, there were a lot of cool things going on with cloud computing as well. I learned a fair amount about MAAS (rapidly deploying thousands of servers) as well as other cloud services like Juju. We saw Mark and the founder of an ARM server company debut a new high density servercluster that runs Ubuntu, and were given some details about just how pervasive Ubuntu is in the cloud computing market. Open source remains ahead of the curve on the server!

The next desktop for Quantal Quetzal is shaping up well too. The best summary was during the Desktop roundtable on friday, where all the topics related to the desktop were discussed and summarized. You can see the notes from this session here. Hopefully will continue to improve how beautiful Ubuntu is, and make the desktop experience even more cutting edge and smooth.

Ubuntu on ARM Showing the Schedule

Welcome Canonical

        Another cool thing I was able to see and learn more about was Ubuntu running on ARM devices. This project is ran by the Linaro Foundation, which is a nonprofit dedicated to bringing open source platforms (Android and Ubuntu) to ARM devices. They’re doing great work, and I even have a PandaBoard to experiment with! The powered all the HD televisions (probably about 20 setups) in the hotel, which displayed the UDS schedule. There’s a picture down below. Its awesome that Ubuntu is running so well on ARM!

From seeing all the bright people working on open source at UDS, it looks like Quantal Quetzal is shaping up to be a great release!

Only in Oakland!

Ubuntu in the Lobby

Posted in Open Source, Ubuntu | 1 Comment

Building Linaro Android (12.04 or daily) for Pandaboard

I recently came into possession of a TI pandaboard for ARM development. Its a pretty cool little package, but if you want to build from source, you run into all sorts of old outdated wiki’s from Linaro that have you chasing your tail trying to build the android tree from source. Here’s how you do it as of May 2012

You have to get a ARM cross-compile toolchain and an android source tree that are in sync with each other. This is the tricky part, because its not exactly well tagged on the internet which version of the toolchain will work with what version of the source tree! When I was trying to match the versions myself, I kept running into all sorts of compile errors because the toolchain tools and the makefiles weren’t based around the same version of the toolchain.

After asking around on IRC, I figured out that linaro makes a build script for each daily/release version that has the URL’s for the proper versions of the source tree and the toolchain. This script is called linaro_android_build_cmds.sh. You can find these scripts on https://android-build.linaro.org/ Just find the build you want to replicate, and find linaro_android_build_cmds.sh in the download section, and download the script. For instance, you can find this script for the 12.04 release is here under the downloads section.

If you want, you can just chmod +x the script and run it. It should download the right files and build on your system. However, if you’re like me and would rather take care of these steps manually, the prebuilt toolchain URL is in avariable in $TOOLCHAIN_URL, and the repo commands and URL to init the android tree are plainly available in the file.

Happy ARM hacking!

Posted in Coding, Hardware, Open Source | Leave a comment

Let the Go hacks begin….

I’ve been tinkering around a bit more and more with Google’s Go language, and I’m finding that I like it more and more.

I think its a great good evolution of compiled languages. A few quick thoughts on what I like so far:

Novel way to handle concurrency

With C or C++, you have to write a pretty big chunk of code to spawn a new thread. With Go, you just have to write
go function(), and its as easy as that!

Furthermore, in C/C++ you’re constantly dealing with locks to ensure data is protected. As you know, this can get pretty hairy. In go, you can set up a system based on locks as well, but you can also use Go “channels”. Talking about Go channels really deserves its own series of articles, but pretty much, a channel is a way that you can instruct independent processes to wait for data to become available, or to signal that data is available. This lets you ensure concurrency without ever having to think in terms of locks and unlocks. Furthermore, you can send arbitrary data types on these channels, allowing you to process data in one thread, and then send the finished result to a waiting thread very easily. Its a novel shake-up to the way concurrency has been thought of in a lot of other languages that I’ve seen.

Garbage Collection

Garbage collection is a nice feature to have in a language. You can make a strong academic case for manual garbage collection, but at the end of the day, its easier to allocate and forget it. I’ve heard that Go’s garbage collector still needs some work (as all collectors do), but I’m sure as the language evolves it will have less and less overhead…

Compiled language

I mostly live in the OS level, and interpreted languages just don’t do in a lot of situations I come across. Having a language that is directly compiled to the architecture’s assembly, and directly executable without any runtimes is something that is great.

Moderately easy C bindings

Go’s authors provide a moderately simple interface to use C code. As with a lot of bindings, its a bit funny at times, but I’ve been using it to great effect to add C functionality to go code.

A Functional Language that’s learned from Object Orientation

You can go back and forth over whether its better to use a functional language or an object orientated language, but I think it just comes down to what you need to use it for. It is indeed nice to be able to tie a set of data to a set of useful functions on them, but at the same time, but at the same time, I find its easy to get bogged down in semantics and formalities of very strict object oriented languages.

Go is a functional language, but it works around with this with some very simple ideas:
1) There are no classes, but there are packages that group similar code together. You don’t have to deal with header files and book-keeping either.
2) In a struct, a data member is accessible globally if its a capitalized, its accessible only within its package if its lowercase. So for instance, foo.bar would be only visible within its package (aka, private), but foo.Bar would be accessible from any code that imports the package (aka, public). Its a simple idea, and I have to say it works great.
3) A struct type may be associated with a function. This lets you designate a function, say Sort, and then tie it to struct. Anyone using the struct can say Foo.Sort(), and the Sort function will get all the data in Foo as a parameter of the function. This too is simple, and works really well.

Real native interface types

Its a compiled functional language, but it gives you access to slices, a powerful way to manage arrays that has native support for a lot of the things C++’s vector library can do (without a lot of the strangeness of that library…)

Really, whether you love functional or object oriented, you should give Go a try!

Posted in Uncategorized | Leave a comment

Good Practices: Compiling from Source #3

In my first post, I wrote about the configuration step in compilation. In my last post, I wrote about the compile step. This post is about the last step, installation.

Rubber Hits the Road

You’ve configured and compiled your project, and all the files that the project needs to run are built and ready to be used. They’re in the build directory after the compile, and need to be put in the filesystem the right way.
For example, if you built a command line executable, it has to be put somewhere where the default $PATH variables can find the executable. It also has to put any libraries it needs in a place where they can be found when the executable runs. These are very particular places, and the install command knows where to put these.

You can install the projects via running:
make install
Likely though, you’re installing to directories that are owned by root, so you might have to do
sudo make install
to get the right permissions.

If your plan is to just install this one custom program, and then never, ever compile another program again, then you’re pretty much done. You can run the program and see if it works now! However, if you plan on compiling a lot of programs, I advise taking a more complicated and flexible approach.

Conquering Chaos

The problem with using “make install” with all the default system directories is that it gets too chaotic too fast if you’re installing dozens upon dozens of custom sources. When you do make install, it can scatter dozens of files accross your filesystem (usually in the standard places for things). If you’re installing dozens of things from source, with dozens of installed files per project, you’ll soon end up with hundreds of files in your filesystem that your package manager doesn’t know about!

Now, if you’ve been doing this for years and years, you’ll end up with a huge amount of old files on your systems, and you never know when you might accidentally use a super old file. Also, you might want to delete a file, but won’t be able to remember where its from or what it does. You should keep the chaos on your system to a minimum, and this takes some careful practice.

What I generally try to do, is leave the standard directories alone, and just let my package manager manage them. If I compile something myself, I will put it in a special folder (a “Kevin-Compiled” folder, if you will), where its easy to keep track, ( and delete ) things I compiled myself if I ever need to. It also makes it easier to monitor the project that you are working on. To give an example, if I install ‘libusb-dev’ for my development via apt-get, I will let my package manager keep track of the files, and upgrade it if necessary. If I compile the source for ‘libusb’ myself, then I will usually install it to /opt/libusb. (some people prefer /usr/local/ to /opt, but /opt is less typing, so thats what I use :D )

Advantages of /opt

  1. If I totally and absolutely screw up an installation of the source I was compiling, recovering from my mistake is as simple as “rm -rf /opt/*” and then re-running the “make install” from the source directories I was working on. If you install to the standard directories, you may not be able to figure out what exactly the install did to your system, and (in extreme cases) could force you to reinstall your whole root partition!
  2. With some clever scripting, you can configure your entire system to run in ‘development mode’ (eg, prefer the libraries in /opt) and then easily switch back to running in ‘normal mode’, by preferring all the libraries that are installed by default by the package manager. If you’re partway through developing something (say, the X server) and its not working, you can always switch modes and get proper functionality back.
  3. You can chown /opt to yourself, and never have to run ‘sudo make install’, you can just run ‘make install’. Its better if you never have to escalate permissions to do a simple development test.
  4. You never overwrite a file that is managed by the package manager. If you have libusb installed by the package manager, and then make install the libusb libraries over the ones installed by the package manager, you’ve overwritten the known-working versions of this library! You’ll have to uninstall that package and reinstall it to get the working version back.
  5. You can see all the files installed by a make install very easy. You can just navigate to /opt, and do “find .” and see each and every file installed by that library! This makes them easy to delete or modify in other ways.

Disadvantages of /opt

  1. This can be difficult to set up, as it takes a fair amount of knowledge concerning how the linker work, how the $PATH variable works, etc.
  2. Its somewhat tedious to manage things this way.
  3. Its oftentimes an extra step to figure out how to instruct the build system to install to “/opt” instead of to “/”. In some frustrating situations, I’ve seen the install directory option even ignored. Most the time this is a simple extra command during the configure.
  4. Sometimes, you can’t cleanly install everything to /opt. For various reasons, sometimes things are hard-coded to your standard paths, and it might take you a second look to figure out why things arent working.
I use the /opt installation, because it mitigates damage, and is worth the setup cost to me because I hardly ever do fresh installs. I’ll blog later about how specifically to set up your system like this well!

Conclusion

I’ve walked through a lot of common problems during the compilation from source that I’ve had to figure out ways to avoid. I’m hoping that this will either help you install things from source by yourself, without forums and wikis, more often, and more easily. Happy coding!

Posted in Coding, Open Source, Ubuntu | Leave a comment

Good Practices: Compiling from Source #2

I went over the first part of compiling (configuring) in my earlier blog post here.

Easy Make Oven

Now, you’ve successfully configured your project, and you’re ready to build. Thankfully, this step is usually pretty straightforward and simple, all you do is type
make
and the project should build successfully. The configure step took care of all the heavy lifting for you, and is why we have that configure step!

Although this step is usually pretty foolproof, there are annoyances and frustrations that can pop up.

The Time, man, the Time!

The first annoyance is that this step can take a long long time! I’m still surprised when coders don’t know about
make -j4
which will compile using 4 threads. This speeds up the compile because it will parallelize the compile along the 4 threads. Also as a side note, the make command will only compile files that have been modified since the last compile. This means that the first compile of a project is always the longest. Then if you go and change a few files, it will only re-compile those few files.

Its Rare, but…

The other annoyance that happens rarely is that builds can be broken. This is rare (especially if you’re not touching the code at all), but it does happen. As a matter of fact, its usually a very strict project policy that before any change goes in, it must at least compile. If someone commits something that doesn’t compile, they’re usually reprimanded and suffer a blow to their reputation! That being said, compiling and compile options can be pretty complex, and sometimes (especially if the build has a lot of build options) things won’t compile right.

What I’ve seen happen a few times is that the configure step doesn’t check for a package it actually needs. If you’re a developer who compiles stuff all the time, you’re likely to have the same subset of files on your computer as every other developer, and might have simply forgot something your project needed when the developer was specifying the configure step. If your build is complaining about not being able to find a header file, try to find it with the methods that were specified in my first post.

If its still broken, you can try to check out a slightly older revision. The idea here is that something in the last few developer changes broke the build, and that going back a few small changes will go back to a version that works. After checking out say, 20 commits back in the past, try making the project again. If it works with the older version, but not the new one, that means you’ve found a regression and can probably report it to the mailing list for the project after you’ve pinpointed the regression commit. You’ve just done your part to make the project better!

If checking out a slightly-older version doesn’t work, you should check your steps over and over again. Its never good to enter an open source project’s mailing list archives with a question about how to compile, so you should try very hard to get it to compile yourself. If you’re really stuck, you can reach out to people for help via IRC or email.

The Last Step

Now your build is done! All the files that this project needs to run are now present in your build directory. Sometimes they’re buried in a few directories, but they’re there, and the build system knows where each and every one is. The last step is to install these in a way that it can work on your computer! Thats the next article though, so stay tuned!

Posted in Coding, Open Source, Ubuntu, Uncategorized | Leave a comment

Good Pracitices: Compiling from Source #1

If you’ve ever been enthusiastic about an open source project, you’ve likely compiled a bleeding edge version of a project before. I know a many non-coders do this, and I can empathize that it is potentially confusing for people.

The basic idea of a build system is to:

  1. ensure that you have all the libraries, tools, and files needed for the project (configure)
  2. be able to compile the program with one command (make)
  3. install the project onto the host system so that it usable (make install)

I’m going to cover #1 today, that is, how to ensure you have what you need, and how to practically work through problems when they pop up. Just so I can give command line examples, I’m going to assume that you’re using a Debian package system (eg, Ubuntu/debian/mint/etc).

First of all, I’ll assume you’ve downloaded the source, and are moderately familiar with the build steps. Most programs use a well known open source build system (commonly Cmake or autotools), and most projects will have a page describing the steps you should take to install. (eg, “./configure && make && make install” for autotools). What I want to help you through is what to do when things go wrong. I’ve compiled a  lot of things, and these are the typical errors I’ll run into…

Finding the Packages You need

Far-and-away the most numerous configure errors you’ll run into are where the build system detects that you don’t have all the packages you need. Any project needs a fair amount of infrastructure to get going. For instance, if you’re trying to build a graphics program, your system has to have two things. It has to have (1) the compiled  files that contain the code that runs the gui (eg, gtk or Qt) and (2) the header files that describe how to use those software libraries. To analogize, the header files are the user manual for the car (the library) that you want to drive! Without these, your program cannot compile.

Now, for a bit of package knowledge. Not everyone needs the header files on the system, and they can take up a bit of room. On Debian packages, the header files are usually placed in the “-dev” package, and the compiled versions are placed in the package library name. For instance, you don’t need the USB header files if you never do any USB development. Most people though want to use the USB port, so the libraries (code to do this) are installed on the system. The library packages are usually named like “libusb-0.1-4″ and contain the libraries. “libusb-dev” contains the header files.

Most the time, when you see an error about a package or header file not being found, that means that you need to install some more packages! I have a few ways to do this. One might be better in one situation than another, and experience will teach you which one to do when.

apt-file

If you see an error about “file.h” not found, that probably means you have to install the headers (the packages that end in -dev). The tool I highly recommend for this is called apt-file. T

his tool will create an index of all the files available to you in the repositories that you have, and give the ability to search for any file. For instance, if I was missing “usb.h”, I would run
apt-file search usb.h
This will return all the files that have the string in them “usb.h”. If you get too many results back, you can search with regular expressions, or you can filter for the “dev” string using grep. If I do
apt-file search \/usb.h | grep dev

I get 4 files back, and the one that makes sense is called “libusb-dev”. It will take experience to figure out which file is the most likely one to install, but its usually pretty obvious after doing it a few times.

cannot find package

Most the time, the -dev packages install something called a “.pc” file. These files are lookup tables that show where exactly all the header files and libraries in a package are. The program pkg-config can parse these files, and give them to the compiler in the way it understands. Run the command
pkg-config --list-all
That’s the list of all the packages that are installed. Those are all the packages that the system knows where the header files are, and how to link to that program while compiling!
Take any one of the things listed by pkg-config –list-all and run this command (libpng as example)
pkg-config libpng12 --cflags --
That is the information that your configure steps are looking for when its looking for a package.

If your compile steps say something about “Package libpng12 not found”, use apt-file to figure out where “libpng12.pc” is by doing
apt-file search libpng12.pc
and install those packages! It will likely resolve your error.

Wrong Version

These are terrible (and thankfully, somewhat rare). I hate getting these errors. This has a lot to with backwards compatibility and what specific functions the target compile needs.

For instance say you’re compiling ProjectX. ProjectX relies on libpotato version 2.13. It cannot use version 2.14 because version 2.14 dropped support for the mega_spud() function. However, the repositories only have the 2.14 version because that is the latest version.

You will have to figure out a way to install libpotato 2.13 on your system. This sometimes requires a separate compile. You should isolate these files from your system, so that most of your system uses all the bug-fixes in libpotato 2.14 for your desktop “Potato Garden” widget.

How do I deal with these? Unfortunately, there isn’t a quick way. I keep maintained a special folder that contains all the strange libraries that I have needed, and I configure my system to know about these. Its a bit of a pain in the backside, but it keeps my filesystem clean, and isolates the older version from what most of the stuff on my system needs. I’ll blog more about how to do this when I talk about the “make install” step in compiling open source stuff.

Funky Stuff

Some programs are just funny, and have funny steps they need. Some need special tools from other packages, others need other strange things. If you run into any of these cases, you probably have to treat them on a case-by-case basis. Google a forum and see what is going on with the funny compile you’re trying to do.

Conclusion

This should give you a way to figure out how to work through most problems you run into during the configure step yourself! Happy coding!

Posted in Coding, Open Source, Ubuntu | 2 Comments

Processor Review: Intel i7 2600k

The Summary:

This processor is insanely fast, and will only set you back about $300.

The Specs:

  • 8 logical cores (4 physical, each hyper-threaded)
  • 3.4 GHz (stock)
  • 32nm
  • 8mb cache
  • Intel HD 3000 Integrated Graphics

This processor has 8 logical cores (4 physical cores, each hyperthreaded) so you’ll have a good experience with any multitasking you might have to do. Cache is pretty big as well.

The Setup:

CPU in actionIntel i7-2600k
Stock Cooler (with Arctic Silver)
2GB DDR3 PC2100
ASrock P67 Extreme4 Gen3 Motherboard
850W Corsair Professional PSU

The Stock Benchmarks:

Passmark has become the go-to standard for processor benchmark s. That being said, this processor ranks pretty highly, and is the first processor under $599 listed.
It is ranked #7 at the time of writing for “high end CPU’s” on passmark.

The Overclocking:

This processor also does pretty well on the overclocked benchmarks over at Passmark, coming in at #8. They say that most people are able to overclock at an average of 31% above stock clock speed, or 4.45Ghz.

There are claims on the internet that you can get this CPU up to 5.1Ghz or higher (+50%) using overclocking and modifying the voltage levels in the CPU. I was unwilling to shorten the lifespan and risk burning out the chip by messing with the voltages on the CPU, but I did get the CPU up to 4.3 GHz stable clock without modifying the default voltage levels, and with the stock cooler. Under load, the processor seems to stay at moderately cool. With this, I reran some compiles I did on the stock install (like the linux kernel), and saw some slight improvement.

This is a great processor, and I’m glad I went with it! I’ll keep mine overclocked at 4.3GHz.

 

Posted in Uncategorized | Leave a comment

The Art of

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil”

–Donald Knuth

 

If you’ve heard of Big-O analysis, or linked lists, or sorting, or searching, or recursion, or pretty much any other thing you as a programmer would know, chances are Donald Knuth was writing about it first in his 1968 book The Art of Computer Programming. The quote above is one of my favorites, and there’s a lot of insight in it.

Put another way, Knuth is reminding us that “over-optimization” from the start leads to unnecessary headaches further down the road, and can even cause projects to end up unfinished and late. Here’s just a few of the dangers that extensive optimization early in a project can lead to down the road:

  • Danger in Completing the Program
    Say you’re creating a physics engine for your game, and need to do a matrix calculation. You could do this the straightforward way, but you decide that CPU operations are too slow. So you write a GPU accelerated matrix library because normal CPU based matrix calculations are slower. After a few weeks muddling around with OpenCL in your side library, your physics engine will be late, or you could have lost the motivation to even finish it.The icing on the cake here is that you don’t even know that your matrix calculations would be a bottleneck in your engine! It could be that the derivatives calculation is really what slows you down to an unacceptable level. By optimizing too early, you optimized something didn’t really need it, and wasted a bunch of time doing so.But hey, at least you’ll have a decent GPU accelerated matrix calculator!
  • Danger in Legibility/Understandability
    It could be faster to unroll loops and make full use of the SSE extension through x86 assembly for some areas of your code. This doesn’t make it easier to understand, and surely obfuscates the meaning of what you’re trying to do! In some circumstances this can’t be avoided, but if you optimize later in the development, you’ll only have your assembly code in limited areas where you really do need it.
  • Danger in Maintenance
    If you have some highly optimized chunks of code, they can be more difficult to adapt to any new changing circumstances, simply because there might only be 1 or 2 people who understand what is going on! If you don’t get what’s going on, changing a nonintuitive optimized chunk of code might introduce corner cases that show up later on as bugs, crashes, or worse. Like with legibility, you want these chunks of code only where you absolutely need them. Optimizing later in the development process will ensure that your complex, hard-to-grasp code is just where you need it to be, and will help out anyone who might have to maintain things later down the road.

Being able to know what to optimize is just as important as deciding what features your project should support. Both are also learned over time; they’re a wisdom that comes with experience (or good project management!)

Posted in Coding, Open Source | Leave a comment

Simple OpenGL Application for Beginners

A friend of mine recently complained that starting OpenGL on Linux is too confusing. In helping him out, I figured out that like most beginners, he couldn’t figure out how to display anything on the screen without 200 lines of confusing code from some tutorial site he found. Furthermore, probably 3/4 these tutorial sites are targeted towards Windows users, so getting it running on Linux is even more confusing!

Learning how to draw an OpenGL triangle on Linux shouldn’t be hard. Most beginners just want a basic scratchpad they can tinker with, not an expansive explanation of what’s going on, and what window manager is doing what, etc. They just want a function that they can plug the beginning OpenGL concepts into.

All you want to see if just starting out is something like this:
So, I whipped up some simple code to do so! Here it is! simple_gl20_triangle.tar.gz

gl.c:

#include "stdio.h"
#include "GL/glut.h"
 
void render()
{
	glBegin(GL_TRIANGLES);
		glColor3f(  1.0, 0.0, 0.0);
		glVertex3f(-0.5, 0.0, 0.0);
 
		glColor3f(  0.0, 0.0, 1.0);
		glVertex3f( 0.0, 0.5, 0.0);
 
		glColor3f(  0.0, 1.0, 0.0);
		glVertex3f( 0.5, 0.0, 0.0);
	glEnd();
 
	glutSwapBuffers();
 
	return;
}
 
int main(int argc, char **argv)
{
        glutInit(&argc, argv);
        glutInitWindowPosition(100,100);
        glutInitWindowSize(500,500);
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
        glutCreateWindow("testwin");
 
        glutDisplayFunc(render);
	glutMainLoop();
 
	return 0;
}

Use the makefile included in the tar package, or compile and run like this:

gcc -o gl gl.c -lglut -lGL -lGLU -lX11 -lXmu -lXi -lm
./gl

Just put whatever commands you want to tinker with in the render() function. I included a makefile to compile. Make sure you have the libglut3-dev and libgl1-mesa-dev packages installed.

Now, there are no animations, and no responses to keyboard or mouse input. (This is possible with glut, but not implemented here). But, this chunk of code should be very useful for trying out just the basics of OpenGL with a linux client for beginners on Linux!

Posted in Uncategorized | Leave a comment

Whirlwind Tour of the Graphics Stack

Graphics drivers have often been a sticking point in the Linux ecosystem. Getting them to work the way you want can be (and historically was) tricky.

Ever wonder why?

The simple answer is that the software stack needed to support graphics cards are complicated. Very complicated.  There are many layers and features the graphics stack needs to run in the way you want it to.

The simple idea is a graphics card is a specialized co-processor. Its really good, and designed for hugely parallelized mathematical computations needed to process 3d images.

A GPU is a distinct processor, so it needs to be programmed by the CPU in order to compute anything. The CPU has to manage all the memory the GPU needs to work with, and it needs to tell the GPU exactly what to do. The CPU needs to assemble all the byte-level instructions for the GPU. And it needs to do all of this on the fly, at least 60 times per second! Quite impressive that it works.

In linux, the chunk of code that makes the commands for the GPU is usually libGL.so. This creates a bunch of memory, and fills commands for the GPU to process. It is, essentially, a real-time assembler that uses OpenGL calls as input. It takes a lot of dynamic, clever coding to get this chunk of code to create the assembly-level instructions for the GPU. Once the commands for the GPU are assembled, and all the graphics buffers have been allocated, managed, and collected, libGL.so is done with its work (for this one frame). Again, this is not a trivial matter. A modern desktop GPU has hundreds of registers to program for each frame. Compare that to the 32 registers an ARM CPU has!

At this point, all the things the GPU needs to do its work are in memory. Commands are assembled, and buffers are allocated. However, all this information was created in userspace! It still has to get through to the kernel (and later, the hardware) somehow. Here’s where the kernel driver kicks in. libGL.so submits all the information to the kernel driver. The kernel driver then takes care of submitting to the hardware to work on. It has to keep track of when and what it submitted, and keep track of when the GPU finishes its work. The kernel driver is an important intermediary between the program that wants to use the GPU and the actual hardware.

When the GPU is done, the kernel driver is told, and eventually, this information gets propogated back to the user of the OpenGL spec. Now we’re ready to do this all over again for the next frame!

If you’ve followed my explanation so far, thats great! :) There’s a lot of other layers of complication like…

  1. We have to deal with virtual memory! The CPU’s virtual addresses are not necessarily the same as the GPU’s virtual address. You have to program various MMU’s to make sure the CPU and the GPU are referencing the same physical address. You have to ensure all the MMU’s are coherent with each other as well…
  2. What about many programs using the OpenGL stack at once? Its possible that there are 2 programs that want to use the hardware concurrently. This adds all sorts of locking and threading.
  3. Say you’re rendering a 1080p (1920×1080) scene, using 32 bit color at 60 frames per second. This is:
    1920 x 1080 x 32 x 60 = 3.9 * 10^9 bits of information per second!
    You have to move 500 megabytes per second onto the framebuffer (screen). By the time you’ve finished watching Hot Tub Time Machine, you’ve consumed more bits of data than the digitalization of the entire Library of Congress. Moving this much data takes special ways and special hardware paths.
  4. GPU’s need initializition and special care to get going….
  5. The graphics stack on the CPU side isn’t simple either… Ever hear of X11?

Its really amazing what goes on every second in a computer. Its also why I like working in graphics!

 

Posted in Uncategorized | Leave a comment