我有一个奇怪的问题,我连续几次调用相同的子程序,处理相同的数据,每次调用我的代码连续更长。我的程序正在做一些矩阵数学,但我在这里问一个更普遍的问题,看看是否有人有同样的问题,所以我不知道具体细节是否重要。下面是我的主程序循环最底层的代码。
use Time::HiRes qw (gettimeofday);
($lus2_sec,$lus2_usec) = gettimeofday();
@blah_LU_v2 = invert_LU_v2(@zmatrix);
($lue2_sec,$lue2_usec) = gettimeofday();
$lu2_elapsed = sprintf("%.3f", ($lue2_sec+($lue2_usec/1000000))-($lus2_sec+($lus2_usec/1000000)));
syswrite STDOUT, "$lu2_elapsed seconds\n";
($lus2_sec,$lus2_usec) = gettimeofday();
@blah_LU_v2 = invert_LU_v2(@zmatrix);
($lue2_sec,$lue2_usec) = gettimeofday();
$lu2_elapsed = sprintf("%.3f", ($lue2_sec+($lue2_usec/1000000))-($lus2_sec+($lus2_usec/1000000)));
syswrite STDOUT, "$lu2_elapsed seconds\n";
每个子程序都在相同的@zmatrix数据上运行,它不会改变。我从每个子程序调用得到了完全相同的答案(之前验证过),所以我知道它并没有搞砸输入数据。子程序也是一个简单的单线程结构,它运行在一个空闲的12核工作站上,内存为96GB。应该没有磁盘交换或CPU问题,因为这台机器有足够的功率来处理这个相对较小的矩阵。但是,程序的输出会产生类似的结果(显然会运行子程序的五次连续调用):
96.485 seconds
99.116 seconds
100.036 seconds
100.615 seconds
101.494 seconds
对于我运行的尽可能多的测试,子程序会慢一点。如果我从命令行终止并重新启动程序,它将在大约96秒后开始,然后每次从那里开始减速。为什么会这样放慢速度?
有问题的子程序如下所示。请注意,我现在使用NYTProf来确定调用Math :: Complex :: _ multiply和_minus的时间。每次调用invert_LU_v2子例程时,它都会对Math :: Complex进行相同数量的调用,但在后续的invert_LU_v2调用中,它们会花费几个百分点。请随意批评我的代码,让我知道我还有什么问题。我是初学者,没有受过训练,也不知道我在做什么。
sub invert_LU_v2 {
my(@junk) = (@_);
my @matrix_local;
my @matrix_L;
my @matrix_B;
my @matrix_inverse;
my $tt;
my $row;
my $col;
my $temp;
my $reduced;
my $normalize = 1;
my $multiplier = 1;
my $dimension = @junk - 1;
for($row=1;$row<=$dimension;$row++){
for($col=1;$col<=$dimension;$col++){
$matrix_local[$row][$col]=$junk[$row][$col];
}
}
for($row=1;$row<=$dimension;$row++){
for($col=1;$col<=$dimension;$col++){
if($row==$col){$matrix_L[$row][$col] = 1;$matrix_B[$row][$col] = 1;}
else {$matrix_L[$row][$col] = 0;$matrix_B[$row][$col] = 0;}
}
}
for($row=1;$row<=$dimension;$row++){
$normalize = $matrix_local[$row][$row];
$matrix_L[$row][$row] = $normalize;
for($col=1;$col<=$dimension;$col++){
$matrix_local[$row][$col] /= $normalize;
}
for($temp=$row+1;$temp<=$dimension;$temp++){
if(($temp != $row) && (abs($matrix_local[$temp][$row]) != 0)){
$multiplier = $matrix_local[$temp][$row];
$matrix_L[$temp][$row] = $multiplier;
for($col=$row;$col<=$dimension;$col++){
$reduced = $matrix_local[$temp][$col] - $matrix_local[$row][$col]*$multiplier;
$matrix_local[$temp][$col] = $reduced;
}
}
}
}
my @y_intermediate;
for($col=1;$col<=$dimension;$col++){$y_intermediate[1][$col] = $matrix_B[1][$col]/$matrix_L[1][1]}
for($col=1;$col<=$dimension;$col++){
for($row=2;$row<=$dimension;$row++){
$y_intermediate[$row][$col] = $matrix_B[$row][$col];
for($tt=1;$tt<=($row-1);$tt++){$y_intermediate[$row][$col] -= ($matrix_L[$row][$tt]*$y_intermediate[$tt][$col])}
$y_intermediate[$row][$col] /= $matrix_L[$row][$row];
}
}
for($col=1;$col<=$dimension;$col++){$matrix_inverse[$dimension][$col] = $y_intermediate[$dimension][$col]/$matrix_local[$dimension][$dimension]}
for($col=1;$col<=$dimension;$col++){
for($row=($dimension-1);$row>=1;$row--){
$matrix_inverse[$row][$col] = $y_intermediate[$row][$col];
for($tt=($row+1);$tt<=$dimension;$tt++){$matrix_inverse[$row][$col] -= ($matrix_local[$row][$tt]*$matrix_inverse[$tt][$col])}
$matrix_inverse[$row][$col] /= $matrix_local[$row][$row];
}
}
return(@matrix_inverse);
}
答案 0 :(得分:3)