Archive

Posts Tagged ‘programming’

Go, Go Go!

August 6, 2010 Leave a comment

Rob Pike is the Google dude who created the Go programming language and he seems to be on a PR blitz to promote his new language. In this interview, “Does the world need another programming language?”, Mr. Pike says:

…the languages in common use today don’t seem to be answering the questions that people want answered. There are niches for new languages in areas that are not well-served by Java, C, C++, JavaScript, or even Python. – Rob Pike

In Making It Big in Software, UML co-creator Grady Booch seems to disagree with Rob:

It’s much easier to predict the past than it is the future. If we look over the history of software engineering, it has been one of growing levels of abstraction—and, thus, it’s reasonable to presume that the future will entail rising levels of abstraction as well. We already see this with the advent of domain-specific frameworks and patterns. As for languages, I don’t see any new, interesting languages on the horizon that will achieve the penetration that any one of many contemporary languages has. I held high hopes for aspect-oriented programming, but that domain seems to have reached a plateau. There is tremendous need to for better languages to support massive concurrency, but therein I don’t see any new, potentially dominant languages forthcoming. Rather, the action seems to be in the area of patterns (which raise the level of abstraction). – Grady Booch

I agree with Grady because abstraction is the best tool available to the human mind for managing the explosive growth in complexity that is occurring as we speak. What do you think?

Abstraction is selective ignorance – Andrew Koenig

Cleanliness And Understandability

While adding code to our component library framework yesterday, a colleague and myself concocted a 2 attribute quality system for evaluating source code:

When subjectively evaluating the cleanliness attribute of a chunk of code, we pretty much agree on whether it is clean or dirty. The trouble is our difference in evaluating understandability. My obfuscated is his simple. Bummer.

Anomalously Huge Discrepancies

I’m currently having a blast working on the design and development of a distributed, multi-process, multi-threaded, real-time, software system with a small core group of seasoned developers. The system is being constructed and tested on both a Sparc-Solaris 10 server and an Intel-Ubuntu Linux 2.6.x server. As we add functionality and grow the system via an incremental, “chunked” development process, we’re finding anomalously huge discrepancies in system build times between the two platforms.

The table below quantifies what the team has been qualitatively experiencing over the past few months. Originally, our primary build and integration machine was the Solaris 10 server. However, we quickly switched over to the Linux server as soon as we started noticing the performance difference. Now, we only build and test on the Solaris 10 server when we absolutely have to.

The baffling aspect of the situation is that even though the CPU core clock speed difference is only a factor of 2 between the servers, the build time difference is greater than a factor of 5 in favor of the ‘nix box. In addition, we’ve noticed big CPU loading performance differences when we run and test our multi-process, multi-threaded application on the servers – despite the fact that the Sun server has 32, 1.2 GHz, hardware threads to the ‘nix server’s 2, 2.4 GHz, hardware threads. I know there are many hidden hardware and software variables involved, but is Linux that much faster than Solaris? Got any ideas/answers to help me understand WTF is going on here?

Highly Skilled

Be careful out there. If you acquire deep expertise and develop into a highly skilled worker in a narrow technical domain, you’re walking a tightrope.You may be highly valued by the marketplace today, but if your area of expertise becomes obsolete because of rapid technological change, your career may stall – or worse. On the other hand, if you luckily “choose” your narrow area of expertise correctly, your skillset may be in demand for life. It’s a classic textbook case of supply and demand.

In the software development arena, consider the ancient COBOL and C programming languages. Hundreds of millions of lines of code written in these languages are embedded in thousands of mission-critical systems deployed out in the world.  These systems need to be continuously maintained and extended in order to keep their owners in business. History has repeatedly shown that the cost, schedule, and technical risks of updating big software systems written in these languages (or any other language) are huge. Thus, because of the large numbers of systems deployed and the fact that most software engineers leave those languages behind (and stigmatize them), the supply-demand curve will be in your favor if you stick solely to COBOL or C programming out of fear of change. The tradeoff is that you’ll spend your whole career in maintenance, and you’ll rarely, if ever, experience the thrill of developing brand new systems with your old skillset.

Categories: technical Tags: , , ,

Cppcheck Test Run

June 22, 2010 2 comments

Since I think that a static code analyzer can help me and my company produce higher quality code, I decided to download and test Cppcheck:

Cppcheck is an analysis tool for C/C++ code. Unlike C/C++ compilers and many other analysis tools, we don’t detect syntax errors. Cppcheck only detects the types of bugs that the compilers normally fail to detect. The goal is no false positives.

After the install, I ran Cppcheck on the root directory of a code base that contains over 200K lines of C++ code. As the figure below shows, 1077 style and error violations were flagged. The figure also shows a sample of the specific types of style and error violations that Cppcheck flagged within this particular code base.

After this test run, I ran Cppcheck on the five figure code base of the current project that I’m working on. Lo and behold, it didn’t flag any suspicious activity in my pristine code. Hah, hah, the last sentence was a joke! Cppcheck did flag some style warnings in my code, but (thankfully) it didn’t spew out any dreaded error warnings. And of course, I mopped up my turds.

Because of the painless install, its simplicity of use, and its speed of execution, I’ve added Cppcheck to my nerd toolbelt. I’m gonna run Cppcheck on every substantial piece of C++ code that I write in the future.

I want to sincerely thank all the programmers who contributed their free time to the Cppcheck project for the nice product they created and unselfishly donated to the world. You guys rock.

Emergent Design

I’m somewhat onboard with the agile community’s concept of “emergent design“. But like all techniques/heuristics/rules-of-thumb/idioms, context is everything. In the “emergent design” approach, you start writing code and, via a serendipitous, rapid, high frequency, mistake-making, error-correction process, a good design emerges from the womb – voila! This technique has worked well for me on “small” designs within an already-established architecture, but it is not scalable to global design, new architecture, or cross-cutting system functionality. For these types of efforts, “emergent modeling” may be a more appropriate approach. If you believe this, then you must make the effort to learn how to model, write (or preferably draw) it up, and iterate on it much like you do with writing code. But wait, you don’t do, or ever plan to do, documentation, right? Your code is so self-expressive that you don’t even need to comment it, let alone write external documentation. That crap is for lowly English majors.

To religiously embrace “emergent design” and eschew modeling/documentation for big design efforts is to invite downstream disaster and massive post delivery stakeholder damage. Beware because one of those downstream stakeholders may be you.

Call Tree

Check out the call thicket, oops, I mean call tree, below. From the root main() node, you can deduce that the 26 function program is written in C. Actually, there are several more than 26 functions because a few of the functions in the model call other lower level functions not shown in the figure.

Even though the functions are cloaked in a sequential numbering scheme, they’re not neatly called one right after another. Intertwined between, around, and across the function calls are a bunch of nested if-then and switch-case statements that make the mess more intimidating. Execution path sequencing is controlled by > 20 statically loaded configuration parameters and several dynamically computed control parameters.

I’ve got to transform this beast into an object oriented C++ design and verify that the new design works. Of course, there are no existing unit, integration, or system tests to reuse. Wish me luck!

Categories: C++ Tags: , , ,

Another Humbler

May 17, 2010 2 comments

It’s often frustrating but always well worth the pain to get humbled from time to time. If it happens often enough, it’ll deflate your head somewhat and keep you on the ground with the rest of your plebe peers. Too much humbling and you lose your self-esteem, too little humbling and you morph into an insufferable, self-important narcissist – like me. One of the reasons why I love zappos.com is that one of their core company values is “Be Humble”.

The other day, I was slinging some code and I was hunting for a bug. In order to slow things down and help expose the critter, I inserted the following code into my program:

//sleep for a second to allow already waiting subscribers a chance to discover us
boost::this_thread::sleep(boost::posix_time::milliseconds(2000));
std::cerr << “\nSleeping For A Bit….. Zzzz\n\n”;

I then ran the sucker and watched the console intently. Low and behold, the program did not seem to pause for the 2 seconds that I commanded. WTF? After the “Sleeping For A Bit” message was printed to the console, the program just zoomed along. WTF? Over the next 10 minutes, I reran the code several times and stared at the source. WTF? Then, by the grace of the universe, it hit me out of the blue:

//sleep for a second to allow already waiting subscribers a chance to discover us
std::cerr << “\nSleeping For A Bit….. Zzzz\n\n”;
boost::this_thread::sleep(boost::posix_time::milliseconds(2000));

Duh! This never happens to you, right?

Now, if I can only practice what I preach; walk the talk.

Categories: C++ Tags: , , ,

Monolithic Redesign

On my latest assignment, I have to reverse engineer and understand a large monolithic block of computationally intense, single-threaded product code that’s been feature-enhanced and bug-fixed many times, by many people, over many years (sound familiar?). In addition to the piled on new features, a boatload of nested if-else structures has been injected into the multi-K SLOC code base over the years to handle special and weird cases observed and reported in from the field.

As you can guess, it’s no one’s fault that the code is a tangled mess. It’s because the second law of thermodynamics has been in action doing its dirty work destroying the system without being periodically harnessed by scheduled acts of husbandry. A handful of maintenance developers imbued with a sense of personal responsibility and ownership have tried their best to refactor the beast into submission; under the radar.

Because the code is CPU intensive and single threaded, it’s not scalable to higher input data rates and its viability has hit “the wall”. Thus, besides refactoring the existing functionality into a more maintainable design, I have to simultaneously morph the mess into a multi-threaded structure that can transparently leverage the increased CPU power supplied by multicore hardware.

Note that redesigning for distributed flexibility and higher throughput doesn’t come for free. Essential complexity is added and additional latency is incurred because each input sample must traverse the 3 thread pipeline.

Piece of cake, no? Since lowly “programmers” are interchangeable, anyone could do it, right? I love this job and I’m having a blast!

C++ Naming Conventions

May 8, 2010 2 comments

For grins, I perused a few books written by several C++ mentors that I respect and admire. I was interested in the naming conventions that they personally use when writing code. Here are the results.

Scott Meyers (Effective C++):

class names – class PhoneBook {};

member function names – void addPhoneNumber(const std::string& pn);

member attribute names – std::string theAddress;

Note: no annotation to distinguish class member attributes from local function variables.

Bjarne Stroustrup (The C++ Programming Language):

I consider the CamelCodingStyle of identifiers “pug ugly” and strongly prefer underscore_style as cleaner and inherently more readable, and many people agree. On the other hand, many reasonable people disagree.

class names – class Phone_book {};

member function names – void add_phone_number(const std::string& pn);

member attribute names – std::string the_address;

Note: no annotation to distinguish class member attributes from local function variables.

Herb Sutter and Andrei Alexandrescu (C++ Coding Standards):

class names – class PhoneBook {};

member function names – void AddPhoneNumber(const std::string& pn);

member attribute names – std::string theAddress_;

Note: they use post-underscores to distinguish class member attributes from local function variables (int clientName_;  //is a class member)

When I’m not constrained by a specific naming standard, I use this one:

class names – class PhoneBook {};

member function names – void add_phone_number(const std::string& pn);

member attribute names – std::string the_address_;

Note: Like Herb & Andrei, I use post-underscores to distinguish class member attributes from local function variables (int client_name_; //is a class member).