when are the arguments to a spawned cilk function evaluated?

when are the arguments to a spawned cilk function evaluated?

Cilkscreen reported a data race in our code. The data race was between the dereference

of a struct pointer so that we could pass a struct to a spawned cilk strand, and a

modificaton to the struct through the pointer after the spawn. We thought that the

arguments to a spawned cilk strand would be evaluation before the strand is created.

We found that cilkscreen reports the data race in the deref.cilk program but not the

deref_works.cilk program. The difference is that we force the struct pointer dereference

before the cilk_spawn rather than in the cilk_spawn function call.

When are the arguments to a spawned cilk strand bound?

If the arguments are bound before spawning the cilk strand, then the deref.cilk program

is correct. However, cilkscreen says that we have a data race between the creation of the

arguments to the spawned function f and the zero of the element on the subsequent line.

This indicates a bug in either the cilk compiler or in cilkscreen.

If the arguments are bound after spawning the cilk strand, the the deref.cilk program

is not correct. However, the cilk programmer's guide is not specific about when

pass by value arguments are evaluated.

If one changes the argument type from a "struct p" to an int, then cilkscreen does not

find any issues. This indicates that the cilk compiler does not handle struct arguments

correctly. This is captured in the deref_int.cilk program.

Downloadapplication/octet-stream Makefile.217 bytes
Downloadapplication/octet-stream deref.cilk644 bytes
Downloadapplication/octet-stream deref_works.cilk668 bytes
Downloadapplication/octet-stream deref_int.cilk587 bytes
2 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Cilk evaluates all function arguments before the spawn.

I've looked into your example briefly and I believe you have found a bug in the compiler. Internally, gcc on x86_64 passes all structs by reference, but should make necessary copies in pass-by-value examples. My guess about what is happening here is that the compiler discovers that f() does not modify its argument and that, therefore, it can avoid an extra copy of the struct. This would be a valid optimization for a serial call, but is incorrect for the cilk_spawn case. I don't have time to test it right now, but I suspect that if you were to modify the argument to f within if, that the compiler would turn off the optimization and cilkscreen would stop complaining. If you have a moment to test this, we'd be interested in the results.

- Pablo

Leave a Comment

Please sign in to add a comment. Not a member? Join today