October 08, 2013
On Tuesday, 8 October 2013 at 20:44:56 UTC, deadalnix wrote:
> On Tuesday, 8 October 2013 at 16:22:25 UTC, Dicebot wrote:
>> On Tuesday, 8 October 2013 at 15:43:46 UTC, ponce wrote:
>>> Is there a plan to have a standard counter-attack to that kind of overblown problems?
>>> It could be just a solid blog post or a @nogc feature.
>>
>> It is not overblown.
>
> I'm certain that most people complaining about it absolutely do not have the constraint that eliminate the possibility to use a GC.

One interesting detail which is rarely explored is that you can "disable" GC for a portion of a program without actually disabling entire GC.

In my current project I have a couple of threads that must never stop, especially not for a garbage collection. These threads manage their memory manually and don't rely on GC (we use reference counting to make sure we don't leak). The rest of the threads, however, make heavy use of the GC, and communicate with "real-time" threads using message passing.

The trick is to spawn *native* threads (i.e. not std.core.Thread threads) so that when stop-the-world occurs, thread_suspendAll() will not block the said threads (because it won't even know about them!).

Per-thread allocator will hopefully make things even more simple.
October 08, 2013
On 10/8/2013 9:22 AM, Dicebot wrote:
> It is simply "@nogc" which is lacking but absolutely
> mandatory.

Adding @nogc is fairly simple. The trouble, though, is (like purity) it is transitive. Every function an @nogc function calls will also have to be @nogc. This will entail a great deal of work updating phobos/druntime to add those annotations.
October 08, 2013
On 10/8/2013 3:02 PM, Peter Alexander wrote:
> You may argue that profiling won't always catch accidental allocations due to
> test coverage. This is true, but then @nogc is only a partial fix to this
> anyway. It will catch GC allocations, but what about accidental calls to malloc,
> mmap, or maybe an accidental IO call due to some logging you forgot to remove.
> GC allocations are just one class of performance problems, there are many more
> and I hope we don't have to add attributes for them all.

This, of course, is the other problem with @nogc. Having a forest of attributes on otherwise ordinary functions is awfully ugly.
October 08, 2013
On Tuesday, 8 October 2013 at 22:37:28 UTC, Walter Bright wrote:
> Every function an @nogc function calls will also have to be @nogc.

Eh, not necessarily. If it expands to static assert(!__traits(hasAnnotationRecursive, uses_gc));, then the only ones that *need* to be marked are the lowest level ones. Then it figures out the rest only on demand.

Then, on the function you care about as a user, you say nogc and it tells you if you called anything and the static assert stacktrace tells you where it happened.

Of course, to be convenient to use, phobos would need to offer non-allocating functions, which is indeed a fair amount of work, but they wouldn't *necessarily* have to have the specific attribute.
October 08, 2013
On 10/8/2013 3:45 PM, Adam D. Ruppe wrote:
> On Tuesday, 8 October 2013 at 22:37:28 UTC, Walter Bright wrote:
>> Every function an @nogc function calls will also have to be @nogc.
>
> Eh, not necessarily. If it expands to static
> assert(!__traits(hasAnnotationRecursive, uses_gc));, then the only ones that
> *need* to be marked are the lowest level ones. Then it figures out the rest only
> on demand.
>
> Then, on the function you care about as a user, you say nogc and it tells you if
> you called anything and the static assert stacktrace tells you where it happened.
>
> Of course, to be convenient to use, phobos would need to offer non-allocating
> functions, which is indeed a fair amount of work, but they wouldn't
> *necessarily* have to have the specific attribute.

What you're suggesting is called "interprocedural analysis" and doesn't work in a system with separate compilation (meaning that function bodies are hidden from the compiler).
October 08, 2013
On Tuesday, 8 October 2013 at 22:45:51 UTC, Adam D. Ruppe wrote:
>
> Eh, not necessarily. If it expands to static assert(!__traits(hasAnnotationRecursive, uses_gc));, then the only ones that *need* to be marked are the lowest level ones. Then it figures out the rest only on demand.
>
> Then, on the function you care about as a user, you say nogc and it tells you if you called anything and the static assert stacktrace tells you where it happened.
>
> Of course, to be convenient to use, phobos would need to offer non-allocating functions, which is indeed a fair amount of work, but they wouldn't *necessarily* have to have the specific attribute.

But is it even necessary? There isn't a great deal of evidence that someone interested in optimization will be blocked on this particular problem, like Peter Alexander said.

GC hassle is quite common but not that big a deal:
- Manu: "Consequently, I avoid the GC in D too, and never had any major problems, only inconvenience." http://www.reddit.com/r/programming/comments/1nxs2i/the_state_of_rust_08/ccnefe7
- Dav1d: said he never had a GC problem with BRala (minecraft client)
- Me: I had a small ~100ms GC pause in one of my games every 20 minutes, more often than not I don't notice it

So a definitive written rebutal we can link to would perhaps be helpful.
October 08, 2013
On Tuesday, 8 October 2013 at 15:43:46 UTC, ponce wrote:
> At least on Internet forums, there seems to be an entire category of people dismissing D immediately because it has a GC.
>
> http://www.reddit.com/r/programming/comments/1nxs2i/the_state_of_rust_08/ccne46t
> http://www.reddit.com/r/programming/comments/1nxs2i/the_state_of_rust_08/ccnddqd
> http://www.reddit.com/r/programming/comments/1nsxaa/when_performance_matters_comparing_c_and_go/cclqbqw
>
> The subject inevitably comes in every reddit thread like it was some kind of show-stopper.
>
> Now I know first-hand how much work avoiding a GC can give (http://blog.gamesfrommars.fr/2011/01/25/optimizing-crajsh-part-2-2/).
>
> Yet with D the situation is different and I feel that criticism is way overblown:
> - first of all, few people will have problems with GC in D at all
> - then minimizing allocations can usually solve most of the problems
> - if it's still a problem, the GC can be completely disabled, relevant language features avoided, and there will be no GC pause
> - this work of avoiding allocations would happen anyway in a C++ codebase
> - I happen to have a job with some hardcore optimized C++ codebase and couldn't care less that a GC would run provided there is a way to minimize GC usage (and there is)
>
> Whatever rational rebutal we have it's never heard.
> The long answer is that it's not a real problem. But it seems people want a short answer. It's also an annoying fight to have since so much of it is based on zero data.
>
> Is there a plan to have a standard counter-attack to that kind of overblown problems?
> It could be just a solid blog post or a @nogc feature.

I thought about an alternative approach:
Instead of using a (yet another) annotation, how about introducing a flag similar to -cov, which would output lines in which the GC is used.
This information can be used by an IDE to highlight those lines. Then you could quickly navigate through your performance-critical loop and make sure it's clean of GC.
October 08, 2013
On 10/8/2013 12:34 PM, Jonathan M Davis wrote:
> I think that it's clear that for some projects, it's critical to minimize the
> GC, and I think that it's clear that we need to do a better job of supporting
> the folks who want to minimize GC usage, but I also think that for the vast
> majority of cases, complaints about the GC are way overblown. It becomes an
> issue when you're doing a lot of heap allocations, but it's frequently easy to
> design D code so that heap allocations are relatively rare such that they
> aren't going to be a serious problem outside of code which is performance
> critical to the point that it would be worrying about the cost of malloc
> (which most code isn't). Personally, the only time that I've run into issues
> with the GC is when trying to do use RedBlackTree with a lot of items. That
> has a tendancy to tank performance.
>
> So, yes, it's problem. Yes, we need to improve the situaton. But for most
> situations, I think that the concern about the GC is way overblown.

+1

Some years ago, a colleague of mine moonlighted teaching remedial algebra at the UW. She'd write on the board:

   x + 2 = 5

and call on a student to "solve for x". The student would collapse in a stuttering heap of jelly, emitting sparks and smoke like a Star Trek computer. She discovered that if she wrote instead:

   _ + 2 = 5

and would ask the same student what goes in the blank spot, he'd say "3" without hesitation.

In other words, the student would only see the words "solve", "x", and "algebra" which were a shortcut in his brain to "I can't do this" and "gee math is hard." She found she was a far more effective teacher by avoiding using those words.

I realized the same thing was happening with the word "template". I talked Andrei into avoiding all use of that word in "The D Programming Language", figuring that we could get people who were terrified of "templates" to use them successfully without realizing it (and I think this was very successful).

We have a similar problem with "GC". People hear that word, and they are instantly turned off. No amount of education will change that. We simply have to find a better way to deal with this issue.
October 08, 2013
On Tuesday, 8 October 2013 at 22:53:35 UTC, Walter Bright wrote:
> What you're suggesting is called "interprocedural analysis" and doesn't work in a system with separate compilation (meaning that function bodies are hidden from the compiler).

Eh, that's not a dealbreaker, especially with phobos and druntime where the source is always available anyway.

Though, my proposed __traits could perhaps be improved to just offer two things:

__traits(getFunctionsCalled, function)

returns a tuple of all functions called. These would ideally be in the form of symbols.

__traits(functionBodyAvailable, function)

true if the source was available to the compiler.


And that's it: the rest is done in the library using existing language features. Then we can decide in library code if a missing attribute is a problem based on if the body was available or not.

Note that this isn't specific to the gc: it would provide the necessary foundation for all kinds of library extensions in the same vein as @safe, with the possibility of automatic inference from the prototype + presence of body.
October 08, 2013
On Oct 8, 2013, at 3:38 PM, Walter Bright <newshound2@digitalmars.com> wrote:

> On 10/8/2013 3:02 PM, Peter Alexander wrote:
>> You may argue that profiling won't always catch accidental allocations due to test coverage. This is true, but then @nogc is only a partial fix to this anyway. It will catch GC allocations, but what about accidental calls to malloc, mmap, or maybe an accidental IO call due to some logging you forgot to remove. GC allocations are just one class of performance problems, there are many more and I hope we don't have to add attributes for them all.
> 
> This, of course, is the other problem with @nogc. Having a forest of attributes on otherwise ordinary functions is awfully ugly.

And we already have a forest of attributes on otherwise ordinary functions.