News for hackers. Stuff that matters.
Re:ISO C is increasingly moronic by haberman on Tuesday December 20, 2011 @07:20PM (#3375823)
> Now, don't get me wrong: There are lot of ways to improve the C language that would make sense: Bitmaps, defined structure packing (think: communication protocol packets), big/little endian variables (data sharing), sensible handling of linked lists etc.

> As ugly as it is, even the printf()/scanf() format strings could be improved, by offering a sensible plugin mechanism, which the compiler can understand and use to issue warnings.

> Heck, even a simple basic object facility would be good addition, now that C++ have become this huge bloated monster language.

As a C user, I would not want to see any of these things in C.

C++ was originally named "C with Classes," and it didn't start out as a monstrosity. Adding "simple" classes to C because C++ is too complicated makes no sense. C++ got complicated because of all of the things that users end up wanting if you walk that path. There's no reason to think that "simple" classes added to C would stay simple.

Plugins for printf()/scanf()?? Not even remotely the kind of thing that needs to be in the core language libraries.

I don't think defined structure packing would really add much; if the idea is to memcpy() the raw data into your structure, then you're just making the actual data processing part more expensive because the compiler has to store the structure in a sub-optimal way (ie. with non-native endianness). Simple expressions like x.y++ could end up being much more expensive than expected.

Re:ISO C is increasingly moronic by tptacek on Tuesday December 20, 2011 @07:39PM (#3375876)
For the past 10 years or so, I've been using an alternative to printf() that I lifted out of Hanson's _C Interfaces and Implementations_; in my tree, it's "fmt.c", and includes the family of fmt_<star> functions. They're just string processing code, and so are trivially portable to WinAPI, OS X, Linux, and FreeBSD.

This is so much of a win that I don't understand why everyone doesn't do it:

* Cross-platform counted/allocated/concatenated string semantics that with no annoying nits from one platform to another.

* "Native" support for printing IP addresses (%i), which gets rid of inet_ntoa and ilk, and binary.

* A registration system for adding new format codes, which is like being able to create Object#inspect functions in C code.

All of which is a roundabout way of saying I agree that we don't need to improve printf/scanf; we need to burn them with fire.

I'm going to tend to believe PHK if he thinks explicit structure packing is a win, noting at the same time how unlikely it is that any implementation of it is going to be a performance bottleneck compared with I/O.

Re:ISO C is increasingly moronic by haberman on Tuesday December 20, 2011 @07:56PM (#3375915)
> I'm going to tend to believe PHK if he thinks explicit structure packing is a win, noting at the same time how unlikely it is that any implementation of it is going to be a performance bottleneck compared with I/O.

I've spent a lot of my life writing parsers for various network formats, and one thing that I can say with authority is that at both my current company (Google) and at my previous company (Amazon) the CPU cost of parsing bytes off the network was noticeable enough to spend significant resources optimizing.

I haven't done benchmarks myself about eg. bitvectors, but I'm pretty sure I've heard that the performance of packed bitvectors is noticeably slower than non-packed. I also think the cost would be comparable to 64-bit math on 32-bit processors (ie. an overhead of 3-5 instructions per operation), which is a non-trivial cost.

Re:ISO C is increasingly moronic by tptacek on Tuesday December 20, 2011 @11:15PM (#3376329)
In the sense that your parsing strategy influences your I/O strategy and, in particular, may incur extra copies, I buy this.

The idea that Amazon has cycle-optimized network parsing code, and that they did it for a significant practical benefit... I have no reason to doubt you, but I'd like to hear more.

I've done a fair bit of high performance network code (not for Amazon or Google, but, for instance, for code watching most of the Internet's tier-1 backbone networks on a flow-by-flow basis) and I'm not sure I could have won much by counting the cycles it took me to pull (say) an NBO integer out of a packet.

This stuff always makes me think about:

http://cr.yp.to/sarcasm/modest-proposal.txt

Re:ISO C is increasingly moronic by haberman on Wednesday December 21, 2011 @02:27AM (#3376713)
> The idea that Amazon has cycle-optimized network parsing code, and that they did it for a significant practical benefit... I have no reason to doubt you, but I'd like to hear more.

I can speak better to Google, since it's my more recent experience. Google's internal data format is Protocol Buffers (and all the code is open-sourced, as you probably know). The C++ code that is generated to parse Protocol Buffers is fast (on the order of hundreds of MB/s) as a result of a lot of optimization. This has reached a rough ceiling of what I believe is possible with this approach (generated C++). Even so, Protocol Buffer parsing code shows up in company-wide CPU profiles, and certain teams in particular have performance issues where Protocol Buffer parsing is a significant concern for them.

To address these issues, I wrote a Protocol Buffer parser that improves performance in two ways:

- it is an event-based parser (like SAX) instead of the protobuf generated classes which are a more DOM-like approach (always parsing into a tree of data structures). With my parser you bind fields to callbacks, and you can parse into any data structure (or do pure stream processing).

- I wrote a JIT compiler that can translate a Protocol Buffer schema directly into x86-64 machine code that parses that schema. Without the intermediate C++ step, I can generate better machine code than the C++ compiler does. In an apples-to-apples test, I beat the generated C++ by 10-40%. If you do more pure stream parsing the win is even greater.

My protobuf work is open source: https://github.com/haberman/upb

> I'm not sure I could have won much by counting the cycles it took me to pull (say) an NBO integer out of a packet.

That's certainly different experience than mine. I don't know much about routers.

Re:ISO C is increasingly moronic by tptacek on Wednesday December 21, 2011 @11:11AM (#3377931)
Bad-ass. I'm happy to be wrong if it solicits comments like this. :)
Re:ISO C is increasingly moronic by swah on Wednesday December 21, 2011 @06:16AM (#3377144)
Is that on your 20%? I noticed you use Lua :)
Re:ISO C is increasingly moronic by mark_h on Tuesday December 20, 2011 @08:20PM (#3375969)
+1 for Hanson's book in general (which I think I might have initially read on your recommendation anyway!). I don't do a huge amount of C programming these days, but it was a huge eye-opener.
Re:ISO C is increasingly moronic by phkamp on Wednesday December 21, 2011 @02:26AM (#3376710)
The reason why struct packing would be a win is probably not performance, but code readability and less bugs.

Making be/le/native conversion a job for the programmer is not only error-prone and a waste of time.

The compiler could safely optimize the byte-swizzles away on non-arithmetic operations, whereas most programmers tend to covert everything before they start working on it.

Re:ISO C is increasingly moronic by __david__ on Wednesday December 21, 2011 @04:57AM (#3376968)
Along those lines I wrote a wishful thinking, blue sky blog post a number of years ago: http://porkrind.org/missives/hardware-friendly-c-structures/
Re:ISO C is increasingly moronic by jetsnoc on Tuesday December 20, 2011 @10:12PM (#3376216)
Thank you for the excellent book suggestion. I've only been writing in C for a few years now. I've been grappling for a better way to manage and abstract some of our utilities in our poorly written legacy application. Every linked list is custom, and every array malloced and freed on the fly -- it's so fragile that sometimes I feel paralyzed. It's been terribly wrong for a long time but I've personally lacked the experience and formal training to make it better through libraries and wrappers. About a year ago I picked up "Mastering Algorithms with C" and it was very helpful at teaching complex algorithms but never really helped me abstract our code base in to something portable and reusable.

I'm certain this book will help me tremendously. :P

Re:ISO C is increasingly moronic by tptacek on Tuesday December 20, 2011 @11:18PM (#3376334)
It is a great, great, great book. Instantly and utterly useful.
Re:ISO C is increasingly moronic by techdmn on Tuesday December 20, 2011 @08:08PM (#3375941)
Sometimes I wonder if C++ deserves more credit for /saving/ C, by absorbing all the crap that might otherwise have been added. :)
Re:ISO C is increasingly moronic by jronkone on Wednesday December 21, 2011 @04:34AM (#3376924)
> Plugins for printf()/scanf()?? Not even remotely the kind of thing that needs to be in the core language libraries.

Where then? As far as I can tell, there's no sensible way to extend the functionality of printf()/scanf(), and compilers special-case their format-strings.

Re:ISO C is increasingly moronic by adgar on Tuesday December 20, 2011 @07:56PM (#3375917)
> Simple expressions like x.y++ could end up being much more expensive than expected.

He's talking about pulling protocol packets off the wire - who increments values in a packet like that? Typically all you ever do is pull the relevant fields out into your own structure or pass them off as arguments to a function call. Which will always involve unaligned reads from buffer somewhere.

The only real way I can see it being misused in a way that results in poor performance is if you read data into an explicitly-packed struct and then pass a reference to it around everywhere, reading from it willy-nilly instead of extracting the values once.

Re:ISO C is increasingly moronic by haberman on Tuesday December 20, 2011 @08:13PM (#3375953)
If you're just going to extract the values once, why not just write the code to actually do that instead of trying to play tricks with memcpy()? Those tricks won't even work in many cases where certain fields indicate the length of certain other fields (which is quite common).

When I first started programming in C I also had this fantasy that I could parse network formats with memcpy(). Since then I've become convinced that writing the actual parsing code is for the best.

Re:ISO C is increasingly moronic by adgar on Tuesday December 20, 2011 @09:21PM (#3376115)
> If you're just going to extract the values once, why not just write the code to actually do that instead of trying to play tricks with memcpy()?

Because it's more expressive, doesn't cost performance, and is less error-prone than writing field extraction code manually. And because it's the type of processing people actually use C for.

> Those tricks won't even work in many cases where certain fields indicate the length of certain other fields (which is quite common).

... it's common for a field to specify the size of the data portion of a packet, not other header fields. The one exception I can think of is a version number, which indicates the layout of the rest of the packet, which isn't exactly rocket science to model using explicitly-packed structs.

> When I first started programming in C I also had this fantasy that I could parse network formats with memcpy().

Nobody here has such a fantasy, they're expressing a desire for this to be made possible.

> Since then I've become convinced that writing the actual parsing code is for the best.

Given a programming language grammar, would you prefer to use an LR parser generator, to write an LR grammar by hand, or to write a recursive-descent LL parser by hand?

Re:ISO C is increasingly moronic by ori_b on Tuesday December 20, 2011 @09:39PM (#3376163)
It seems that the preferred implementation these days is to write an LL parser by hand, if most production compilers and interpreters are anything to go by.
Re:ISO C is increasingly moronic by adgar on Thursday December 22, 2011 @11:13PM (#3384589)
There are some well-publicized LL parsers - C# for example - but I'm not convinced by "most production compilers and interpreters."