Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark and optimize calls from Julia to GAP functions #68

Closed
fingolfin opened this issue Oct 11, 2018 · 1 comment
Closed

Benchmark and optimize calls from Julia to GAP functions #68

fingolfin opened this issue Oct 11, 2018 · 1 comment
Assignees
Labels
kind: enhancement New feature or request

Comments

@fingolfin
Copy link
Member

fingolfin commented Oct 11, 2018

Now that calls from GAP to Julia have been improved a lot, the same should be done for the other way around.

Right now, GAP function calls from Julia are handled via this function:

function(func::GapFunc)(args...)
    arg_array = collect(args)
    result = ccall(Main.gap_call_gap_func,Any,
                        (MPtr,Any),func.ptr, arg_array )
    return result
end

And then call_gap_func is defined like this:

jl_value_t * call_gap_func(void * func, jl_value_t * arg_array)
{
    jl_array_t * array_ptr = (jl_array_t *)arg_array;
    size_t       len = jl_array_len(array_ptr);
    Obj          arg_list = NEW_PLIST(T_PLIST, len);
    SET_LEN_PLIST(arg_list, len);
    for (size_t i = 0; i < len; i++) {
        SET_ELM_PLIST(arg_list, i + 1, gap_julia(jl_arrayref(array_ptr, i)));
        CHANGED_BAG(arg_list);
    }
    Obj return_val = CallFuncList((Obj)(func), arg_list);
    if (return_val == NULL) {
        return jl_nothing;
    }
    return julia_gap(return_val);
}

Note that this always creates a plist, even if there is no argument, or only a few. Then the GAP kernel function CallFuncList in most cases (for <= 6 arguments) will extract the entries of this plist (and effectively discard the plist afterwards, in that it won't be referenced anymore afterwars), and then invoke optimized function dispatchers for 0 to 6 arguments.

My guess is that we can get a measurable speedup by providing multiple function call handlers on the Julia side, namely for 0 to 6 arguments, and the current one is retained for calls with more arguments. This then of course needs to be matched on the GAP side (in the JuliaInterface kernel extension) with (probably rather simple) call handlers.

However, I strongly suggest to create some benchmarks first, like I did for calls the other way around, to see whether this has the desired effect of improving performance (and reducing memory pressure, by allocating fewer temporary plists).

@fingolfin
Copy link
Member Author

This was taken care of by PR #104; well, no benchmarking was done, but call_gap_func was optimized at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants