You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In QuEST v4, a user-given list of qubits is copied into a std::vector<int> which is passed down through ~10 functions before finally being processed by the backend. Currently each receiving function signature looks like:
voidf(vector<int> list) {
...
}
and ergo receives a copy of list. This means called functions can safely modify their argument list (which is done frequently, e.g. sorting and updating elements) without corrupting the caller's copy. This is defensively designed, and makes a nice, concise signature.
This does however invoke superfluous copies. Though the lists are small (<64 elements) such that each copy is fast and negligible compared to the runtime of the subsequent statevector simulation, there are many copies invoked between the user's call and the backend simulation. I would estimate ~20 due to all the validation calls, etc. For decreasing number of qubits in the state, the relative cost of the copies vs the backend simulation increases (but not hugely; of course the lists themselves shrink with decreasing qubits).
An alternative approach is to pass by const reference, so that internal function signatures resemble
voidf(const vector<int>& list) {
...
}
These involves no copying, and the use of const ensures the callee cannot mutate and corrupt the caller's list. The few functions in the call chain that need to modify the list would explicitly instantiate their own copy (a small boilerplate evil of copy = list). It is my understanding a compiler cannot automatically avoid the copying between translation units since it cannot know whether an external function mutates (that's a point in Julia's favour).
Alas, this solution is ugly to me! It adds 6 new characters in every internal function signature which receives a vector, of which there are hundreds. While "receiving a const reference" is standard C++ practise, one could argue it is not essential here given the relative size of the lists.
So: do the evils of superfluous copies outweigh the added boilerplate of const-refs? Is this a premature optimisation, or encouraged standard C++ practise? Can compilers miraculously optimise away copies and make this consideration moot through some magical mechanism??
A similar consideration can be made for structs, like Qureg and CompMatr which are also presently passed-by-copy. These are rather small and fixed-size, so their copy penalties are negligible, but could be made references for consistency with vectors if we changed those to refs.
I welcome any and all thoughts!
The text was updated successfully, but these errors were encountered:
In QuEST v4, a user-given list of qubits is copied into a
std::vector<int>
which is passed down through ~10 functions before finally being processed by the backend. Currently each receiving function signature looks like:and ergo receives a copy of list. This means called functions can safely modify their argument
list
(which is done frequently, e.g. sorting and updating elements) without corrupting the caller's copy. This is defensively designed, and makes a nice, concise signature.This does however invoke superfluous copies. Though the lists are small (<64 elements) such that each copy is fast and negligible compared to the runtime of the subsequent statevector simulation, there are many copies invoked between the user's call and the backend simulation. I would estimate ~20 due to all the validation calls, etc. For decreasing number of qubits in the state, the relative cost of the copies vs the backend simulation increases (but not hugely; of course the lists themselves shrink with decreasing qubits).
An alternative approach is to pass by const reference, so that internal function signatures resemble
These involves no copying, and the use of
const
ensures the callee cannot mutate and corrupt the caller's list. The few functions in the call chain that need to modify the list would explicitly instantiate their own copy (a small boilerplate evil ofcopy = list
). It is my understanding a compiler cannot automatically avoid the copying between translation units since it cannot know whether an external function mutates (that's a point in Julia's favour).Alas, this solution is ugly to me! It adds
6
new characters in every internal function signature which receives a vector, of which there are hundreds. While "receiving a const reference" is standard C++ practise, one could argue it is not essential here given the relative size of the lists.So: do the evils of superfluous copies outweigh the added boilerplate of const-refs? Is this a premature optimisation, or encouraged standard C++ practise? Can compilers miraculously optimise away copies and make this consideration moot through some magical mechanism??
A similar consideration can be made for structs, like
Qureg
andCompMatr
which are also presently passed-by-copy. These are rather small and fixed-size, so their copy penalties are negligible, but could be made references for consistency with vectors if we changed those to refs.I welcome any and all thoughts!
The text was updated successfully, but these errors were encountered: