Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
December 27, 2015 each! vs foreach parallel timings | ||||
---|---|---|---|---|
| ||||
I'm doing some re-writing and measuring. The basic task is to take 10K samples (in struct S samples below) and calculate some metrics (just per sample for now). It isn't evident to me how to write the parallel foreach in the same format as each!, so I just used the loop form that I understood. Measured times below are for processing three simple metrics 100 times on 10K samples. This parallel mode could be very useful in my work, which involves processing a bunch of hardware performance data. This is on windows, corei5, DMD32 D Compiler v2.069.2, debug build. each! time:59 ms parallel! time:20 ms import std.stdio; import std.algorithm; import std.conv; import std.range; import std.typecons; import std.parallelism; import std.array; import std.traits; import std.datetime; struct S { int sn; ulong a; ulong b; ulong c; ulong d; double e; ulong f; ulong m1; double m2; double m3;} void apply_metrics(int i,ref S s){ with(s){ m1 = a+b; m2 = (c+d)/e; m3 = (c+f)/e; sn = i; } } int main() { S[10000] samples; // initialize some values foreach ( int i, ref s; samples){ int j=i+1; with (s){ a=j; b=j*2; c=j*3; d=j*4; e=j*10; f=j*5; } } auto sw = StopWatch(AutoStart.yes); // apply several functions on each sample, also number the samples foreach(j;iota(100)) samples[].each!((int i, ref a)=>apply_metrics(i,a)); writeln("each! time:", sw.peek().msecs, " ms"); auto sw2 = StopWatch(AutoStart.yes); // do the same as above, but in parallel foreach(j;iota(100)) foreach( i, ref a; parallel(samples[])){ apply_metrics(i,a);} writeln("parallel! time:", sw2.peek().msecs, " ms"); return 0; } |
December 27, 2015 Re: each! vs foreach parallel timings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | On 12/27/2015 11:30 AM, Jay Norwood wrote: > samples[].each!((int i, ref a)=>apply_metrics(i,a)); Are you using an older compiler? That tuple expansion does not work any more at least with dmd v2.069.0 but you can use enumerate(): samples[].enumerate.each!(t=>apply_metrics(t[0].to!int,t[1])); > foreach( i, ref a; parallel(samples[])){ apply_metrics(i,a);} That does not compile because i is size_t but apply_metrics() takes an int. One solution is to call to!int: foreach( i, ref a; parallel(samples[])){ apply_metrics(i.to!int,a);} To not answer your actual question, I don't think it's possible. :) Ali |
December 28, 2015 Re: each! vs foreach parallel timings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Sunday, 27 December 2015 at 23:42:57 UTC, Ali Çehreli wrote:
> On 12/27/2015 11:30 AM, Jay Norwood wrote:
>
> > samples[].each!((int i, ref a)=>apply_metrics(i,a));
>
> Are you using an older compiler? That tuple expansion does not work any more at least with dmd v2.069.0 but you can use enumerate():
>
> samples[].enumerate.each!(t=>apply_metrics(t[0].to!int,t[1]));
>
> > foreach( i, ref a; parallel(samples[])){
> apply_metrics(i,a);}
>
> That does not compile because i is size_t but apply_metrics() takes an int. One solution is to call to!int:
>
> foreach( i, ref a; parallel(samples[])){ apply_metrics(i.to!int,a);}
>
> To not answer your actual question, I don't think it's possible. :)
>
> Ali
The code I posted was compiled with v2.069.2. It isn't creating a tuple return value in this code. I'll re-check it.
|
December 28, 2015 Re: each! vs foreach parallel timings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | > On Sunday, 27 December 2015 at 23:42:57 UTC, Ali Çehreli wrote:
>> That does not compile because i is size_t but apply_metrics() takes an int. One solution is to call to!int:
>>
>> foreach( i, ref a; parallel(samples[])){ apply_metrics(i.to!int,a);}
>>
It builds for me still, and executes ok, but must be because size_t and i are both 32 bits on Win32 build.
|
December 27, 2015 Re: each! vs foreach parallel timings | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | On 12/27/2015 04:17 PM, Jay Norwood wrote:
>> On Sunday, 27 December 2015 at 23:42:57 UTC, Ali Çehreli wrote:
>>> That does not compile because i is size_t but apply_metrics() takes
>>> an int. One solution is to call to!int:
>>>
>>> foreach( i, ref a; parallel(samples[])){
>>> apply_metrics(i.to!int,a);}
>>>
>
> It builds for me still, and executes ok, but must be because size_t and
> i are both 32 bits on Win32 build.
>
Makes sense. I would still prefer size_t and even leave it out for the lambda:
void apply_metrics(size_t i,ref S s){
// ...
sn = i.to!int;
// ...
samples[].each!((i, ref a)=>apply_metrics(i,a));
Ali
|
Copyright © 1999-2021 by the D Language Foundation