我试图理解并行分配以尝试加速一些小操作。我运行以下脚本(警告它耗尽了我的内存并将我锁定),我发现它随着向量中的行数呈指数级减慢。
for(i=1, i<=5, i++,
t = [59760, 71220, 79380, 83820, 3300, 11400, 27900, 39060, 43500, 51300,56220, 60];
t = repeat(t, 10^i);
n = nitems(t);
diff = t[2::n]-t[1::(n-1)];
day_v = diff < 0;
st = HPTime();
day_cum = cumulative Sum([0]|/day_v);
tot_cum = HPTIme() - st;
st= HPTime();
day_break = loc(day_v); // this will give you last row of the day
// make a matrix n x number of day breaks
m = J(n, nitems(day_break), -1);
parallel assign({db = day_break},
// make the item a 1 if it's row is higher than the corresponding row
m[a, b] = a > db[b];
);
m;
// now just sum the matrix
day = VSum(m`); // +1; // if you want the day to start at 1
tot_pa = HPTime() - st;
show(n, tot_pa, tot_cum);
);
我不希望并行分配比cumulativesum() 更快,但我很好奇并行分配是如何工作的。
我读了这我猜这是因为它为每个线程创建非常大的矩阵的副本?
有谁对它如何运作有任何其他见解,也许还有一些并行分配的基本注意事项?
好点,我没有想到我的例子不是同类比较。谢谢@Craige_Hales ,这个确实很有用。
并行分配做得非常出色! 我认为数组 m 的大小是实际问题:它正在突飞猛进地增长,或者每次迭代增长 100 倍。
| 我 | 尼特姆(米) | Seconds_in_Parallel_Assign | Seconds_in_Nested_Loops |
| 1 | 2,400 | 对于 tikseconds() 来说太小 | .18 |
| 2 | 240,000 | .033 | 19 |
| 3 | 24,000,000 | 3.3 | 1951年 |
| 4 | 2,400,000,000 | 第338章 | 放弃了等待 |
那个剧本,
m[a, b] = a > db[b];
每秒执行约 700 万次(4-CPU 17.5G VirtualBox)。 我的内存也用完了,这意味着寻呼。 分页会导致速度急剧下降,也许在 i==5 时。
第 4 列(嵌套循环比较)的制作方式如下(屏幕截图...计算机正忙于尝试达到第 3 行的 1900 秒):

这是并行分配问题的设计目的。 部分速度来自 C++ 循环而不是 JSL 循环,部分来自线程。