How to improve the performance of this piece of code?

I'm trying to find out a little Julia, after reading the instructions for several hours, I wrote the following code fragment:

ie = 200;
ez = zeros(ie + 1);
hy = zeros(ie);

fdtd1d (steps)=
    for n in 1:steps
        for i in 2:ie
            ez[i]+= (hy[i] - hy[i-1])
        end
        ez[1]= sin(n/10)
        for i in 1:ie
            hy[i]+= (ez[i+1]- ez[i])
        end
    end

@time fdtd1d(10000);
 elapsed time: 2.283153795 seconds (239659044 bytes allocated)

I believe it is optimized because it is much slower than the corresponding version of Mathematica:

ie = 200;
ez = ConstantArray[0., {ie + 1}];
hy = ConstantArray[0., {ie}];

fdtd1d = Compile[{{steps}}, 
   Module[{ie = ie, ez = ez, hy = hy}, 
    Do[ez[[2 ;; ie]] += (hy[[2 ;; ie]] - hy[[1 ;; ie - 1]]);
     ez[[1]] = Sin[n/10];
     hy[[1 ;; ie]] += (ez[[2 ;; ie + 1]] - ez[[1 ;; ie]]), {n, 
      steps}]; Sow@ez; Sow@hy]];

result = fdtd1d[10000]; // AbsoluteTiming
{0.1280000, Null}

So how to make Julia version fdtd1dfaster?

+4
source share
2 answers

Two things:

When the function is first launched, the time will include the compilation time of the code. If you want apples to compare apples with a compiled function in Mathematica, you have to run the function twice and the second run time. With your code, I get:

elapsed time: 1.156531976 seconds (447764964 bytes allocated)

for the first run, which includes compilation time and

elapsed time: 1.135681299 seconds (447520048 bytes allocated)

, .

-, , , , . .

:

function fdtd1d_local(steps, ie = 200)
    ez = zeros(ie + 1);
    hy = zeros(ie);
    for n in 1:steps
        for i in 2:ie
            ez[i]+= (hy[i] - hy[i-1])
        end
        ez[1]= sin(n/10)
        for i in 1:ie
            hy[i]+= (ez[i+1]- ez[i])
        end
    end
    return (ez, hy)
end

fdtd1d_local(10000)
@time fdtd1d_local(10000);

Mathematica ,

{0.094005, Null} 

@time fdtd1d_local:

elapsed time: 0.015188926 seconds (4176 bytes allocated)

6 . .

+5

, . . , , .   , . .

:

ie = 200;
ez = zeros(ie + 1);
hy = zeros(ie);

fdtd1d (steps)=
    for n in 1:steps
        for i in 2:ie
            ez[i]+= (hy[i] - hy[i-1])
        end
        ez[1]= sin(n/10)
        for i in 1:ie
            hy[i]+= (ez[i+1]- ez[i])
        end
    end

@time fdtd1d(10000);

julia> 
elapsed time: 1.845615295 seconds (239687888 bytes allocated)

:

ie = 200;
ez = zeros(ie + 1);
hy = zeros(ie);

fdtd1d (steps)=
    for n in 1:steps


        ez[2:ie] = ez[2:ie]+hy[2:ie]-hy[1:ie-1];
        ez[1]= sin(n/10);
        hy[1:ie] = hy[1:ie]+ez[2:end]- ez[1:end-1]

    end

@time fdtd1d(10000);

julia>
elapsed time: 0.93926323 seconds (206977748 bytes allocated)
0

Source: https://habr.com/ru/post/1537341/


All Articles