1. Strange benchmark result for Phix vs Eu 3.1.1

I was messing about with file benchmarks and came across a case where Phix is much slower than Eu 3.1. The benchmark requires 100 files to be created on disk, with each file containing 1000000 random bytes. The program for Eu is...

constant 
    BUFFER_SIZE = 10000, 
    SizeOfFile = 1000000, 
    FilesToWrite = 100, 
    randbuff = repeat(255, BUFFER_SIZE) 
 
integer cnt, fptr, blen 
atom tend, tstart 
tstart = time() 
 
for NFiles = 1 to FilesToWrite do 
    fptr = open(sprintf("f%d.dum", NFiles), "wb") 
    cnt = SizeOfFile 
    blen = BUFFER_SIZE 
 
    while cnt > 0 do 
        if cnt < blen then 
            blen = cnt 
        end if 
 
        puts(fptr, rand(randbuff[1..blen]))         -- EU 
        -- puts(fptr, sq_rand(randbuff[1..blen]))   -- PHIX 
        cnt -= blen 
    end while 
 
    close(fptr) 
end for 
 
tend = time() 
printf(1, "Execution time = %3.2f\n", tend - tstart) 

On my setup with Eu 3.1.1, this runs in about 5 sec. Very reasonable. With Phix 0.7.6 (change the rand call to sq_rand) it takes almost 13 sec. I have verified that it's the sq_rand call that makes the big difference by removing all the file stuff and just generating random data.

The sawn-off Eu benchmark code is...

constant 
    BUFFER_SIZE = 10000, 
    SizeOfFile = 1000000, 
    FilesToWrite = 100, 
    randbuff = repeat(255, BUFFER_SIZE) 
 
integer cnt, blen 
atom tend, tstart 
sequence p 
tstart = time() 
 
for NFiles = 1 to FilesToWrite do 
    cnt = SizeOfFile 
    blen = BUFFER_SIZE 
 
    while cnt > 0 do 
        if cnt < blen then 
            blen = cnt 
        end if 
 
        p = rand(randbuff[1..blen])         -- EU 
        -- p = sq_rand(randbuff[1..blen])   -- PHIX 
        cnt -= blen 
    end while 
end for 
 
tend = time() 
printf(1, "Execution time = %3.2f\n", tend - tstart) 

The timings are now Eu: 4.5 sec, Phix: 12.4 sec.

Since I know in this case that the random buffer has no nested sequences, I wrote my own function which avoids the nested call to sq_rand as follows...

function bsq_rand(object a) 
    for i = 1 to length(a) do 
        a[i] = rand(a[i]) 
    end for 
    return a 
end function 

Using bsq_rand instead of sq_rand in the code above gives Phix: 4.21 sec.

So I know how to improve the Phix benchmark result but it surprised me how big the difference in time is.

Is this related to the other discussion on function calling?

new topic     » topic index » view message » categorize

2. Re: Strange benchmark result for Phix vs Eu 3.1.1

lesterb said...

Since I know in this case that the random buffer has no nested sequences, I wrote my own function which avoids the nested call to sq_rand as follows...

function bsq_rand(object a) 
    for i = 1 to length(a) do 
        a[i] = rand(a[i]) 
    end for 
    return a 
end function 

Using bsq_rand instead of sq_rand in the code above gives Phix: 4.21 sec.

So I know how to improve the Phix benchmark result but it surprised me how big the difference in time is.

In case you didn't know (though I expect you did), the actual definition for sq_rand is in builtins\psqop.e:

global function sq_rand(object a) 
    if atom(a) then return rand(a) end if 
    for i=1 to length(a) do 
        a[i] = sq_rand(a[i]) 
    end for 
    return a 
end function 
lesterb said...

Is this related to the other discussion on function calling?

Yes, with another little bugbear: after/with s[i] = <tmp>, the compiler should somehow mark <tmp> as unassigned/zero (since it then is), and not need to test/decref/deallocate it, but it don't...

Anyway, modifying builtins/psqop.e to:

global function sq_rand(object a) 
    if atom(a) then return rand(a) end if 
    for i=1 to length(a) do 
--      a[i] = sq_rand(a[i]) 
        object ai = a[i] 
        ai = iff(atom(ai)?rand(ai):sq_rand(ai)) 
        a[i] = ai 
    end for 
    return a 
end function 

Then I get RDS Eu (2.4): 3.40s, Phix: 3.48s

Putting a[i] = ai on a separate line allows the nested call to use pbr, otherwise it would double-up on that test/decref/deallocate bugbear (which is still there, not that you could legally remove it for a named temp, ai in this case).

I'll make that change for the next release, to solve this specific problem, but yes, there's room for some more general improvement, somehow.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

3. Re: Strange benchmark result for Phix vs Eu 3.1.1

Thanks Pete.

I did the mod in my psqop.e and Phix now runs the benchmark faster than Eu - which is as it should be blink.

I was thinking of using the Win function CryptGenRandom to fill an allocated buffer with random bytes in one shot (which is very fast). I think that may be a legitimate tactic, but my Eu/Phix coding is a bit stale at the moment and I can't think how to get a buffer of bytes output without using more external functions.

Perhaps I'll try it just to see how it performs.

Thanks again.

Regards,

Les

new topic     » goto parent     » topic index » view message » categorize

4. Re: Strange benchmark result for Phix vs Eu 3.1.1

Just to round off this topic, and for idle interest only, I made a Phix version of the benchmark that uses cryptgenrandom.

It creates 100 files, each containing 1000000 random bytes in 2.06 sec. Not too shabby. smile

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu