Archive: January 26, 2025
Archive: January 26, 2024
Archive: January 26, 2023
Thanks for your comments on the comments? survey. Please vote if you haven't already.
I've dug into this a bit, and while it's possible to use Twitter as comments for a blog, it's not straightforward. Wish it was and wish Twitter cared enought to make this easy - would be a great resource for news websites as well as blogs. (Imagine if every Wikipedia page had one! :)
The perfect experience is, links to your blog posts appear on Twitter. Each of these Tweets has a Reply button. Each blog post has a Reply button, which does exactly what the Reply button on Twitter does. Each of these Tweets has a link to display the Tweet and all its Replies. Each blog post has a Comments button, which links back display the Tweet and all of its Replies.
Appears to do the parts in bold above I have to dive into the Twitter API, with oauth and application Ids and all the rest of it. So be it. I have applied to be an authorized Twitter developer. Stay tuned...
[Update: yep, trying Mastodon...]
|
Okay, ready? Here's another post in the series about CUDA and GPU acceleration. (And yes, sadly, this is the last one, at least for the moment...)
We've tackled basic CUDA, multithreading, grids, and memory models. Now let's talk about streams!
This diagram shows using a GPU with a grid of blocks and threads:
Back in the grids discussion we showed we could run 120,000 blocks of 1,000 threads, vastly accelerating our processing with massive parallelism. So what can be done beyond that?
As you can see in this diagram, the whole grid is invoked as a single kernel with a single call. The Device goes off and does whatever it is asked to do - organized as blocks of threads - and then completes. But what if you want to run more than one kernel at the same time? This isn't really a way to get more parallelism of the same task, its more a way to do different things at the same time.
When a kernel is invoked, it is always as part of a stream. There is an implicit "stream zero", and all the things we've done so far in our examples have used this stream. If we want to run different kernels at the same time, we can define more streams, and put each one in a different stream. The operations in each stream are serialized with respect to that stream, but asynchronous with respect to other streams. (There are ways to synchronize to a stream, as we shall see.)
Here's what using a GPU w multiple streams looks like:
In the Host thread, we make multiple kernel invocations into different streams. Each stream runs in parallel on the Device. The Host can synchronize with all streams or with any one stream. And as we'll see, it's also possible for a Device to signal the Host from within a stream.
Let's break up the processing of our example program still further. Let's provide for the possibility to have multiple streams. Here's hello7.cu which implements this (as before, that's a link to the source code if you want to try this yourself):
The changes are highlighted above. First, at the top, highlighted in yellow, we've added yet another parameter to specify the number of streams, with a default of 1.
In the main() function, also highlighted in yellow, we've added a loop. For each stream we call cudaStreamCreate() which returns a handle of type cudaStream_t. These handles are stored in an array named cs. On the kernel invocation, we've added a new fourth parameter to specify the stream. We didn't do this before, and the default was "stream zero". Specifying a stream means all the processing done for that kernel - the whole grid of blocks of threads - all happens within that stream. Invoking another kernel into a different stream means they will run asynchronously relative to each other, sharing the Device resources.
As before, after all the kernels are invoked into all the streams, we call cudaDeviceSynchronize() to wait for them all to complete. If we had wanted there is also a function cudaStreamSynchronize() which synchronizes the Host to a given steam. In this case wanted to wait for all of them. And then finally we have to call cudaStreamDestroy() to clean up the resources for each stream.
Okay so that's great, we're running multiple streams, but now we have to divide up the work between the streams, otherwise they'll all just do the same thing. These changes are highlighted in green.
We've added two new parameters to the domath() global function which is the main line of the kernel, to pass the stream index, and the number of streams. These values are then used in the calculation of index and stride inside the domath() loop. With this logic each stream processes only its portion of the blocks.
One other change, not directly related to streams, is highlighted in turquoise at the top of main(). We added a call to cudaGetDeviceProperties(), so we could display some interesting information about our particular GPU, like the kind of Device, amount of Graphics Memory, number of stream processors, and number of cores per processor. This call can also be used to determine if the Device supports Host and Managed memory models.
Okay, well that wasn't too difficult. Let's try running hello7, what will happen?
The first of these runs used one stream, so this is exactly like when we ran hello6 before. The second run broke up the processing into 10 streams. You can see, the number of blocks in each stream is one-tenth of the number of blocks in the first run, so we had 10 streams of 55,458 blocks of 1,024 threads. This was faster, by 1.1s.
Once again we can see, the allocation and initialization of the arrays, and copying them back and forth to the Device takes far longer than the computation itself. Marvel at the fact that in the second run, the entire computation on three 5GB arrays took 0.26s. This is GPU acceleration in action!
Also note the information displayed about the device. This particular GPU is a NVidia GeForce RTX 3080, it has 16GB of Graphics Memory, 58 stream processors, and 1,536 cores per processor. No wonder it can process so many operations in parallel!
There's one other thing I wanted to share with you. CUDA has the ability to call Host functions inline in a Device stream. This is useful for a bunch of reasons, such as if you want to know when a kernel has completed processing of some data, or needs more input.
The following sample program hello8.cu includes a simple example of this:
I haven't included the entire source listing, because the changes are only at the bottom. Highlighted in yellow, we've added a call to cudaLaunchHostFunc(). This call specifies a stream, and a Host function to be called, in this case streamdone(). You can also pass a parameter which is in turn passed to the Host function. The streamdone() function simply writes a message, but of course you could do more, such as signaling a Host thread to take some action.
Now when we run hello8, it looks like this:
As planned, when each stream completed its kernel invocation, the next stem in the stream was calling the Host function, which wrote out a message. In this case the streams completed in the order they were started, but that wouldn't necessarily be the case if the workloads were different.
So that's it! At least for now :) Hope you enjoyed this series, and please let me know if you have comments or questions, and especially corrections... good luck parallelizing!
|
This picture is called "straight lines". Whoa. Almost feel the pull of local gravity bending the light...
Slashdot: what happens when an AI generates designs for PC cases? This! Excellent...
I wonder about the design constraints ... would these be buildable, and would they work (cooling, power, etc.)?
MarkTechPost: Top innovative AI powered healthcare companies. Such an explosion of these, some are doing great work and creating value, others will be gone with nary a mark left. Investor appetite for these is high.
For example: MIT researchers develop an AI model that can detect future lung cancer risk. Early detection translates into better outcomes for patients.
This makes so much sense: Smart TVs as digital health devices. All you need is a camera+microphone. The pointing device on modern remotes is more than good enough for input.
And AI in medical imaging market projected to reach $20.9B by 2030.
I think I mentioned this already: Microsoft expands 'multibillion dollar' deal with OpenAI, creators of ChatGPT. $10B. They also just laid off 10,000 people. That $10B might have paid the salaries of those 10,000 people for 10 years. But this is clearly strategic, and some of the things Microsoft decided not to keep doing - like AR/VR - are not.
Fox: California reels from string of mass shootings despite having some of the strictest gun laws in US. So, we need even more laws, right?
Jeremy Clarkson: We're in the midst of a coup. Who the hell’s behind it? Huh.
Brad Feld reviews Please report your bug here. "I hope there are a lot more books like this. It balances startup stuff with the cynicism of the experience while placing it in a fictional world. It unexpectedly merges with believable near-term science fiction, which has a delicious parallel universe theme." Sounds excellent, on the list!
Dilbert gives relationship advice. Hmmm...
Interesting, from the Financial Times: We tried to run a social media site and it was awful. They put up a Mastodon server and it was a lot of work. And also, the legal, security, and reputational risks.
Yet another reason, if any were needed, why I'd rather not host comments here.
Erik Sink continues his investigation into "native AOT" for .NET. This time he considers storage allocation and objects. Once again we see how much easier it is to have managed code and garbage collection :)
Meanwhile, Tim Bray releases Quamina, an open-source pattern-matching library. Glad to see he's keeping busy :)
From the pages of history: Gorbachev and Louis Vuitton. "Can there be any doubt who won the cold war?"
|
Archive: January 26, 2022
Archive: January 26, 2021
Archive: January 26, 2020
(click to enbiggen)
This is rather a remarkable collection (thanks Gerard van der Leun). It looks a lot more like giving people fish than teaching people to fish, even if some of the fish are given in the guise of teaching. It most definitely vears into mutilated beggar territory, in which bad behavior is rewarded by "help". So what is the answer?
|
Had a nice quiet day having lunch with my granddaughter and mother. So cute together.
John Favini in Slate: What if competition isn't as "natural" as we think? An interesting think piece but sadly misses the rather obvious truth that collaboration *is* a way to compete.
Jason Kottke: The story of two monks and a woman. A beautiful little fable.
Heh, this was a literal LOL for me; I spent years working on JPEG2000. And it was great for digital pathology images; qualitatively better than JPEG. But... standard browsers do not support it, so...
(BTW the xkcd image is a JPEG :)
Can you solve the two-fuse puzzle? "Imagine that you're making a magic potion. You're a wizard with a long beard. But - the potion only works if you wait exactly 45 minutes before you stir it. If you stir it before or after the potion's totally ruined. You don't have a smartphone. You don't have a watch. You don't have any kind of time measuring device. What you have is two fuses of irregular consistency. The one thing you know for a fact is that it takes an hour for each of these fuses to burn from one end to the other. How do you use these to measure exactly 45 minutes?" I'm a sucker for these ... stay tuned!
[Update: solved!]
Paper airplanes. Excellent.
In which once again it is shown, that design flourishes in the presence of constraints...
Seth Godin: toward the honest job interview.
-
The candidate thinks, “I really need this job.”
-
The hiring manager thinks, “I'm tired of this, I really need to fill this job.”
-
As a result, the candidate says what he thinks will get him hired.
-
As a result, the hiring manager isn't really listening, not really.
It's so critical to hire the right people. And so hard.
Had me at hello: Rare, Mohawk-Wearing Fish Discovered ‘Walking’ on Seafloor.
Joel Spolsky: the Stack Overflow age. I've known Joel since his Joel-on-Software days, before his Citydesk days (and yes, this blog is *still* made with Citydesk), and Stack Overflow is just about the best thing ever. Remember the days before you could Google for the answer to any technical question? I do, and they were ... not as good.
Apropos: RIP Citydesk.
Jeff Atwood (Joel's partner for Stack Overflow): Let's encrypt everything. I've always thought there was no reason to encrypt access to this blog ... but maybe ... I should?
Jamie Zawinksi: offsite backup. The Rosetta Disc is now safely installed on 67P/Churyumov-Gerasimenko. "In 2014 the Rosetta Probe landed on Comet 67P/Churyumov-Gerasimenko, where it measured the comet's molecular composition. It will remain at rest as the comet orbits the sun for hundreds of millions of years. So somewhere in the solar system, where it is safe but hard to reach, a backup sample of human languages is stored, in case we need one." Good to know.
Powerline: better living through chemistry, the settled science. GMOs are one of the miracles of the world, like vaccines; we've figured out how to feed way more people and have way fewer infectious diseases. Like nuclear power, it's a complete mystery why environmentalists have ended up on the wrong side of this issue. It's almost like they don't care about the science, they just want to be mad about something...
Finally, in the wake of Australia's terrible bushfire season: "Hope" is born at Zoo Miami. "For the third time in the zoo’s history and the first time in over 28 years, a surviving koala has been born at the zoo!! Though the actual “birth” took place on May 30th of last year, it was only yesterday that the joey (baby koala) first came completely out of the pouch!"
Onward...
|
Archive: January 26, 2019
Archive: January 26, 2018
Archive: January 26, 2017
Archive: January 25, 2016
Just another manic Monday ... up with the sun, gone with the wind ... get up, stand up ... working for the weekend ... the song remains the same.
This is cool ... the Mercator Puzzle reminds you how deceptive maps can be. Reminds me of that time I discovered there are ten time zones in Canada...
Speaking of maps, I thought this one was pretty interesting; a map of party affiliations in Congress as of the last election. Of course those blue patches include the largest cities like New York, Los Angeles, and Chicago...
This was simply a news item at Thanksgiving, but I think it is going to be most important: Google unveils app streaming. With this technology it is not necessary to preinstall an app on your phone, instead, when you visit a website the app is automagically downloaded and executed. Absolutely seems like the way to go, right?
To be read: Ian McDonald's Luna. "Luna has no government: it has contracts. You get to the moon by entering into a contract with the Lunar Development Corporation - the nice folks who'll be selling you your air, bandwidth, carbon and water for the rest of your life - and everything you do afterwards is also contractual: marriage, employment, and, of course, criminal redress." Sounds about right...
Les Johnson: Mars. "Since I work for NASA and have looked extensively at the technologies required to send people to Mars, I am often asked how close we are to being able to take such a journey. Basing my opinion solely on information that is publicly available, the answer is… not straightforward. Let me break it into the three areas that Project Managers and Decision Makers use when they assess the viability of a project in an attempt to explain my answer." Yeah, but ... never tell me the odds :)
This incredible twisted building slash bridge is actually an art museum which spans a river in Norway. Wow! Just when you think you've seen it all...
Lytro introduces the "Immerge" 360o camera for cinematic virtual reality. This stuff is getting real, fast. And maybe - just maybe - this will be the application which drives adoption of Lytro's innovative camera technology, which can "focus" after an image is captured.
So cool: This glass-bottomed sky pool will be suspended 115' in the air. The glass will be 8" thick. Imagine the weight of all that water... wow. Doesn't seem possible, does it?
Introducing the IBM Swift sandbox. All you need now to start writing Swift is a web browser. That's super cool, but I wonder if it will really foster adoption. So far the Swift train has not really started rolling, despite Apple's enthusiastic backing.
Global warming notwithstanding, you may find this useful: how to drive in the snow, in a regular-ass car, without freaking out. "You are not actually required to lose your goddamn mind just because snow is falling. It is not the apocalypse. Neither physics nor society have been cancelled by it." Hehe.
This is pretty cool: Circular bridge in Uruguay lets drivers slow down and enjoy the view. Seems like bridge designers often take the opposite tack, and deliberately block the view so drivers are not distracted.
|
Archive: January 26, 2015
A quiet day of work today. Work work work. A little rain, a little sunshine, and a little news.
I hardly ever watch "news" video online, do you? But this one caught my eye: Whale watchers celebrate epic season. So that's good news right? Or is it bad news ... I can never remember which way climate change is supposed to cut. The picture of a gray whale at left is on the climate.org website, listed as an endangered species.
Meanwhile they're having a huge storm in the Northeast, almost exactly a year after the NYTimes declared "the end of snow".
What all this means to me is that climate science is not actually science. There are huge variations in weather from year to year, but nobody yet understands the longer term trends. And to the extent that they are understood, very little is changing. Nothing to see here, move along.
This is pretty cool (NPI): Robot finds fish beneath Antarctic ice. "When a group of scientists drilled through 2,430 feet of ice in Antarctica to get to the water underneath, they only expected to find a few microbes here and there. Instead, they discovered a thriving community of fish and crustaceans." Unlike climate "science", this is real science; a theory and an experiment to test it which modifies the theory.
Wow I need one: The Taco toaster. Crunchy tacos without frying in oil...
But of course: Worry for Solar Projects after End of Tax Credits. Too bad all that money is being wasted on subsidies for non-viable tech.
I'm installing the latest Windows 10 Technical Preview. The more I read, the more I'm convinced this will be my next OS. You may ask, why not OS X? Good question. I guess I just like Visual Studio for C++ development...?
|
Archive: January 26, 2014
Yesterday was the most beautiful day ever, or close enough; today is overcast and muggy. Blech. With reading on the dock taken right out, I guess I'll have to blog :) ...
Where are you in the great :) vs :-) debate?
Last night saw Dallas Buyers Club and liked it more than I thought I would (and obviously I thought I would like it). Matthew McConaughey should totally win best actor for this. After seeing such a movie one wonders why people like American Hustle or Her. No special effects or weirdness, just an interesting story with interesting characters. And ... movement!
Two keyboards ... okay, quick; which is "better"? Which is the more recent version? I do not like IOS 7, Sam-I-am. I do not like it.
Related: Microsoft gives new Office Apps a new, flatter look. Blech. Rats following each other into the sewer, IMHO.
Hard to believe: 1+2+3+... = -1/12. Seriously?
Glenn Reynolds makes DayByDay: It doesn't get any better than this. It does seem like colleges are ready to be disrupted, but will it happen all at once (Uber?) or slowly over time...
Speaking of disruption: Arienne's business model is in trouble. The Euro space launcher was designed to compete with Boeing, not SpaceX. Still, this isn't quite disruption; the value proposition hasn't changed, just the economics.
An analysis of last December's shopping: The Tipping Point (e-commerce version). It's a pretty clear trend. People are no longer just shopping online, they're buying there, too.
Sigh: The Great Mom and Dad experiment. The federal government spent nearly a billion dollars to help poor couples stay together, with almost nothing to show for it. I'm shocked. Make it less expensive, and it will just happen.
Excellent: the Norwegian Curling team's Olympic uniforms. They have already won. You've got to love curling, what a great "sport", right?
Scott "Dilbert" Adams wonders: Can robots own money? Well, maybe not legally, but with bitcoin, they can practically...
Lenovo to buy IBM's server business (for $3.2B). Seems like IBM are throwing their furniture into the fire, what shall be left?
Why have IBM sold their server business? Amazon. Um, yeah. Who needs to buy a server anymore, when you can lease them as you need them for such low cost?
But... are IBM doomed? I think perhaps not, there may be lots of business in building software and integrating applications; now that hardware is commoditized, this is where the margin is...
Opportunity celebrates 10 years of roving Mars. Awesome! Not bad for a 90-day mission. And still going strong...
Seen on Facebook: "Maybe we should start emailing each other copies of the Constitution, so we know the government have read it". Ouch.
Finally, today's Eichhorn picture: a squirrel snacking in the snow. Isn't he adorable?
|
Archive: January 26, 2013
Archive: January 26, 2012
Archive: January 26, 2011
This morning after an early Yoga class I sought out the famous Encinitas "boat houses", and there they were.
pure awesomeness
|
Archive: January 26, 2010
A [rare] mid-morning filter pass...
Pondering Jevons paradox: the proposition that technological progress that increases the efficiency with which a resource is used, tends to increase (rather than decrease) the rate of consumption of that resource. As in for example, energy conservation decreases the price of fuel (more efficiency, more supply, less demand) which increases usage of the fuel. Hmmm...
Once again, truth is stranger than Onion: Zimbabwe introduces $100,000,000,000,000 note. That my friends is what inflation looks like. Sure, laugh, but don't laugh too hard, people who live in glass houses...
I posted this the other day, but I need you to look at it again. Go ahead, look at it (click through to enbiggen). What we have here is a Yak, in the middle of a cliff. It is unclear how the Yak got there in the first place, or why, or where it is going, but it is clearly amazing.
Everything old is new again: Mr. Edison's Kindle. A compendium of ideas slightly ahead of their time...
If you're like me, you love RSS. (And in this, we are unlike most others; for reasons I have not completely grasped, RSS has failed to take the world by storm, despite being massively useful.) Anyway if you love RSS you will occasionally or not so occasionally happen across website which don't have feeds. Gasp! And if you're exactly like me, you'll make a homemade feed for it, but if you're not, you might check out Google's "follow changes on any website" capability. In which they make a feed for just about anything. Cool.
So... how much is a good idea worth? Jeff Atwood considers the question. "The value of my advice is debatable. But you would do well to heed the advice of Mr. Sivers and Mr. Catmull. If you want to be successful, stop worrying about the great ideas, and concentrate on cultivating great teams." Amen.
Today I came across a great new book from Steve Krug: Rocket Surgery Made Easy. I was already a fan; Don't Make Me Think was great. And so I decided to give everyone in my team a copy, via Kindle, since I know they all have Kindles :) But guess what? There is no way to give a specific book to someone on their Kindle! I guess that must be Amazonian rocket surgery. So I ended up giving everyone a gift card instead.
This is awesome: Landis wins Bahamian time trial. "Floyd Landis won the timetrial in the three-stage Tour of Bahamas this week-end. The former OUCH-Maxxis rider reportedly beat the course record set by David Zabriskie in 2008." And check out that bike - nice TT bars :)
Do you know how much football is actually played in a typical 60-minute game? Eleven minutes. "So what do the networks do with the other 174 minutes in a typical broadcast? ...commercials take up about an hour... 75 minutes...is spent on shots of players huddling, standing at the line of scrimmage or just generally milling about between snaps." Action packed! (No wonder I love my Tivo :)
Today's ZooBorn: A baby Dik-Dik! A miniature version of a miniature deer :)
|
Wow, how the mighty have fallen.
And this on the eve of the State of the Union address, too.
Interestingly Obama has disappointed liberals like the New Yorker by failing to do enough,
even while disappointing conservatives like me by doing too much.
As Victor Davis Hanson notes: Obama In Free Fall.
I must say I am *still* rooting for him, we need a successful President.
But I'm no longer optimistic, he's squandered the goodwill which was his best chance.
|
Archive: January 26, 2009
In Vista today, and it is cold... did a ride tonight on my mountain bike (you'll remember my road bike is being repaired in the wake of my weird disaster) and basically froze the whole way. Spent most of the day coding in PowerPoint :) You can get it to do almost anything, but some things are easier than others...
Well, let's make a filter pass, shall we?
Tonight I was listening to Santana, selected by my philosopher iPod, and it reminded me of riding in the Netherlands back in May. It was much warmer then, but I was riding a clunky cruiser I'd rented there, and riding my mountain bike on the street brought back the memories. One nice thing about clunky bikes is you have a built in excuse to take it easy, so you can cruise without pushing yourself. The Dutch sign at left notes "he who rides quietly sees much". I'm still one of their kind...
Supercool: An HD tour of the International Space Station, conducted by Commander Mike Fincke. This is not a movie, this is real (although it looks like a movie :). Amazing. And how nice is it that we can have this sort of tour without military censorship or anything like that; fifteen nations are involved in the ISS, and people from everywhere can view these videos. [ via Slashdot ]
Wired ran a great timeline picture: 25 years of the Mac. (click to enbiggen amazingly.) Of all the stuff in that picture, all the great products etc., the thing that stands out the most is the [original] iMac. That turned the company around, and everything since is history.
I love Wired, but I noticed this too: Wired's February issue is three millimeters thin. A sign of the times, I'm afraid. Noticed the same thing about the latest issue of Sports Illustrated; despite the upcoming Superbowl it is a slim vestige of its former self, due to the dearth of ads of course. I hope Wired and Sports Illustrated make it; they're both examples of things print media can do that online cannot.
As an aficionado of giant images, I had to note this: Gigapan Imager used to craft 1,474 megapixel image of Obama's inauguration. Very cool.
Eric Raymond: The Sound of Empire Falling. "Microsoft’s valuable Windows franchise appears vulnerable after two decades of dominance. Revenue for the company’s Windows operating system fell for the first time in history in the last quarter of 2008. The popularity of Linux, a free operating system installed on many netbooks instead of Windows, forced Microsoft to lower the prices on its operating system to compete." A classic Christensonian attack from below?
Related: David Hornik pleads Enterprise Software is not Dead Yet. While reports of its death may be exaggerated, that "yet" in David's title tells you he knows how the story ends.
|
Archive: January 26, 2008
|
So, now that I am converting a bunch of movies from MPEG4 to Quicktime using Visual Hub, and able to watch them on my AppleTV, Shirley and I are watching more movies. Somehow the subtle increase in easy of doing so has changed our habits. Either of us (or both) could easily jump in the car and drive over to Blockbuster, but we don't do it. And Netflix requires premeditation. We've had OnDemand movies from Time Warner for a while through our Moxi, but all of those movies suck (mostly). So there you are, once again technology changes the world. In a small way, at least. Although I must tell you, we're eagerly anticipating iTunes Movie Rentals on the AppleTV itself, I think that might change the world in a little bit bigger way. We'll see...
In the meantime, last night we re-watched Under the Tuscan Sun, and it was fun! (
The other night we watched A Good Year, and it was good - thanks, Tim :) On tap for tonight, No Reservations... |
|
|
Archive: January 26, 2007
Archive: January 26, 2006
Archive: January 26, 2005
Archive: January 26, 2004
Archive: January 26, 2003
If you're programming in 2003, you're most likely coding in either C++ or Java. These languages are quite similar syntactically, and provide a solid, well-defined way to package functionality in objects. They also share a common defect, they make it difficult to hide interface details from implementation details. I have the solution - read on!
The Problem
In a typical class, you have a header file <class>.h and a code file <class>.cpp. The header contains the class definition. The class's public properties and methods define the interface details of the class. This is the information users of the class need. The class's private properties and methods define the implementation details of the class. This information is only used in the code file, it is not needed by any user of the class. But, because both sets of properties and methods are in the same header file, all users of the class "see" the implementation details. This is the defect.
Before prescribing a solution, let me explain why this is a defect. First, it is ugly, and by W=UH this means it is wrong. Second, whenever the implementation data are changed, the header changes. This causes all users of the class to require recompilation. But changing the implementation should never affect any users of the class! Third, changing the private properties and methods may change the size of the class's data. This implementation-only change can affect users. Consider the following example:
_____ myclass.h _____ class myclass { private: int theInt; public: myclass(void); int getInt(void); void putInt(int theInt); };
_____ mycaller.cpp _____ ... void myfunc(void) { myclass localInt; int stackInt; ...
This shows a simple class which encapsulates an integer, and a simple caller which instantiates it. Let's say we change the class slightly, as follows:
_____ myclass.h _____ class myclass { private: int theInt; int counter; public: myclass(void); int getInt(void); void putInt(int theInt); };
The new implementation datum is highlighted in green. Even though this is only a change to the implementation, it will break the caller! Because the size of the myclass object has changed, the location of stackInt will change. Not only will every user be recompiled because the class header changed, but every user has to be recomplied, because the size of the object has changed. All for an implementation-only change. A defect indeed.
The Solution
Okay, now on to the solution. The crux of the problem is that the implementation details (the private properties and methods) are defined in the class header. So let's pull them out of the header, shall we? Instead of defining private properties and methods in the class header, let's create a new internal class to "package" the implementation details. This class will be defined in the code module for the class. Only a pointer to the internal class will appear in the header. Here's the class header with this organization:
_____ myclass.h _____ class iclass; // warn compiler iclass is a class
class myclass { private: iclass *icp; // internal data object pointer public: myclass(void); int getInt(void); void putInt(int theInt); };
As you can see, there is only one private datum defined in the class header, a pointer to the internal class. Here's the code module for the class:
_____ myclass.cpp _____ ... #include "myclass.h" // external class definition
class iclass { // internal implementation class public: // everything in iclass is accessible int myInt; }; ... myclass::myclass (void) { // class constructor icp = new iclass; // instantiate internal object ... } ... myclass::~myclass () { // class destructor ... delete icp; // destroy internal object } ... int myclass::getInt (void) { // class method return (icp->theInt); // access internal data though pointer } ...
Note that the internal class is defined right in the code module, there is no need to define it in a separate header, because this is the only place it will be used. If we want to add a new datum to the implementation, we just go ahead and do it in the code module:
_____ myclass.cpp _____ ... #include "myclass.h" // external class definition ... class iclass { // internal implementation class public: // everything in iclass is accessible int myInt; int counter; };
myclass::myclass (void) { // class constructor icp = new iclass; // instantiate internal object icp->counter = 0; // can perform initialization here... ... } ... myclass::~myclass () { // class destructor ... delete icp; // destroy internal object } ... int myclass::getInt (void) { // class method icp->counter++; // internal-only data return (icp->theInt); // access internal data though pointer } ...
Again, the changes are highlighted in green. Only the code module is affected; the class header did not change, and none of the users of the class have to be recompiled. Isn't this pretty? It must be right :)
This technique is sometimes called a "Cheshire Cat" class, after John Carolan, an early C++ pioneer. The lone private pointer to the internal data object is called "the smile", of course...
More Advanced Example
The example above was pretty simple, but more advanced stuff can be done with an internal class. In particular, this class can have internal-only methods. Here's an example of this in action... the external class remains the same as in the examples above, so all this only affects the code module.
_____ myclass.cpp _____ ... #include "myclass.h" // external class definition
class iclass { // internal implementation class public: // everything in iclass is accessible iclass(void); // internal class can have constructor int getInt(void); // as well as other methods... int myInt; int counter; };
iclass::iclass (void) { // internal class constructor counter = 0; // perform initialization here... }
int iclass::getInt (void) { // internal class method counter++; return (myInt); } ... myclass::myclass (void) { // class constructor icp = new iclass; // instantiate internal object ... } ... myclass::~myclass () { // class destructor ... delete icp; // destroy internal object } ... int myclass::getInt (void) { // class method return icp->getInt(); // access internal data though methods } ...
In this example, a constructor for the internal class has been added, as well as a method. Because the internal class has addressability to all class data (by definition, since the class is used to encapsulate those data), there is no reason not to use internal class methods for all "local" subroutines, instead of private methods of the external class. As with private data, this has the dual advantages of "hiding" the implementation details, since they are not in the class header, and isolating users of the class from any changes to those details.
This organization has other benefits as well. Suppose the class uses another class internally for implementation. For example, say the myclass defined above instantiated a cString object. In the standard organization, this would mean placing a #include "cString.h" in the myclass header, even though the cString object is only used internally. This exposes any users of myclass to changes in cString! By separating the internal data into an internal class only defined in the code module, the #include "cString.h" is only needed in the code module. All users of myclass remain blissfully unaware that a cString is being used. Now if cString changes only the code module for myclass would have to be recompiled, and that makes sense, because myclass uses a cString.
There you have it - a clean solution to a troublesome problem.
Caveat: Some readers have pointed out that there is overhead inherent in this technique. For each object instantiation, there is another internal object instantiated, and the data required by each object is increased by the size of the private pointer plus the allocation overhead for another object (typically 16 bytes). There are also extra calls to new and delete for each object allocation and destruction. This is all true. For tiny objects which are allocated and destroyed rapidly, the overhead may be unacceptable. In most cases this overhead disappears into the noise, and the added elegance and maintainability are well worth it.
[ Later - for more please see How to Write C++ Classes II... ]
[ Later still - I am indebted to several readers for comments and suggestions which improved and simplified this technique, including Eric Holm, Klitos Kyriacou, and Horacio Peña. Thanks! ]
|
When I'm coding, I usually listen to music. I either listen to MP3s, bring up Live365, or use Real Player's Radio feature. The last week or so I've been listening to Jazz Network through Real Player. No commercials, just a clean 132bps stream of beautiful jazz... I just noticed Jazz Network is in Germany. Wow. All those little packets of sound are travelling deep under the Atlantic Ocean just to reach my ears. The music industry is so screwed! Why would anyone buy music?
|
Don't know which was a worse beating, Bucs over Raiders or Kasparov over Deep Junior. Neither was a good game, nor close. My favorite ad was the one where Ozzie Osborne wakes up in bed with Florence Henderson, after dreaming his kids turned into the Osmonds. Dumbest was the Bud Light upside-down drinker. Who thought of that one?
Joel seems to have run into Murphy's Law. Poor guy. Everyone out there does have current backups, right?
FuturePundit: Cloning, Biotech, and the Future of the Family. Very interesting! An angle affecting the gene pool of the future I had not considered before...
Real Networks and Major League Baseball have announced they will collaborate to webcast virtually all MLB games next season. At $10/month only early adopters will try it, but this is an interesting trend. For many radio has already moved to the web, maybe TV will also? You still have the problem that the TV is in the family room, the computer is in the office... of course 802.11g may solve that.
|
|
|