On 2011-03-21 09:50:09 -0400, dsimcha <dsim...@yahoo.com> said:

On 3/21/2011 8:37 AM, Michel Fortin wrote:
Well, it'll work irrespective of whether shared delegates are used or
not. I think you could add a compile-time check that the array element
size is a multiple of the word size when the element is passed by ref in
the loop and leave the clever trick as a possible future improvements.
Would that work?

On second thought, no, but for practical, not theoretical reasons: One, you can't introspect whether a foreach loop is using a ref or a value parameter. This is an issue with how opApply works.

Indeed a problem. Either we fix the compiler to support that, or we change the syntax to something like this:

        taskPool.apply(range, (ref int value) {
                ...
        });

Or we leave things as they are.

Two, AFAIK there's no way to get the native word size.

Right. That's a problem too... you could probably alleviate this by doing a runtime check with some fancy instructions to get the native word size, but I'd expect that to be rather convoluted.

I'd like to check if I understand that well. For instance this code:

        int[100] values;
        foreach (i, ref value; parallel(values))
                value = i;

would normally run fine on a 32-bit processor, but it'd create low-level a race on a 64-bit processor (even a 64-bit processor running a 32-bit program in 32-bit compatibility mode). And even that is a generalization, some 32-bit processors out there *might* have 64-bit native words. So the code above isn't portable. Is that right?

Which makes me think... we need to document those pitfalls somewhere. Perhaps std.parallelism's documentation should link to a related page about what you can and what you can't do safely. People who read that "all the safeties are off" in std.parallelism aren't going to understand what you're talking about unless you explain the pitfalls with actual examples (like the one above).


Unfortunately, I'm going to have to take a hard line on this one. The issue of integrating std.parallelism into the race safety system had been discussed a bunch in the past and it was basically agreed that std.parallelism is a "here be dragons" module that cannot reasonably be made to conform to such a model.

About the "cannot reasonably be made to conform to such a model" part: that is certainly true today, but might turn out not to be true as the model evolves. It certainly is true as long as we don't have shared delegates. Beyond that it becomes more fuzzy. The final goal of the module shouldn't be to bypass safeties but to provide good parallelism primitives. By all means, if safeties can be enabled reasonably they should be (but as of today, they can't).

And I totally agree with you that it's quite silly to require casts everywhere to use synchronized. I'll be the first to admit that it's hard to see synchronized classes being very practical as they're implemented today. There's room for improvements there too.


Given the choice (and I hope I'm not forced to make this choice) I'd rather std.parallelism be a third-party module that's actually usable than a Phobos module that is such a PITA to use that noone does in practice.

Which is understandable.

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/

Reply via email to