Module basic_dsp::combined_ops
[−]
[src]
This module allows to combine certain operations into one operation. Since one many machines the speed of many DSP operations is limited by the memory bus speed this approach may result in better register and cache usage and thus decrease the pressure on the memory bus. As with all performance hints remember rule number 1: Benchmark your code. This is especially true at this very early state of the library.
With this approach we change how we operate on vectors. If you perform
M
operations on a vector with the length N
you iterate wit hall other methods like this:
// pseudocode: // for m in M: // for n in N: // execute m on n
with this method the pattern is changed slightly:
// pseudocode: // for n in N: // for m in M: // execute m on n
Both variants have the same complexity however the second one is beneficial since we have increased locality this way. This should help us by making better use of registers and CPU caches.
Only operations can be combined where the result of every element in the vector is independent from any other element in the vector.
# Examples
use std::f32::consts::PI; use basic_dsp::*; use basic_dsp::combined_ops::*; let a = RealTimeVector32::from_array(&[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]); let b = RealTimeVector32::from_constant(0.0, 8); let ops = multi_ops2(a, b); let ops = ops.add_ops(|a, b| { let a = a.scale(2.0 * PI); let b = b.clone_from(&a); let a = a.sin(); let b = b.cos(); let a = a.multiply_vector(&b).abs(); let a_db = a.log(10.0).scale(10.0); (a_db, b) }); let (a, b) = ops.get().expect("Ignoring error handling in examples"); close(&[0.80902, 0.30902, -0.30902, -0.80902, -1.00000, -0.80902, -0.30902, 0.30902], b.data()); close(&[-3.2282, -5.3181, -5.3181, -3.2282, -159.1199, -3.2282, -5.3181, -5.3181], a.data());
Structs
ComplexFreqIdentifier |
Placeholder for a concrete vector. |
ComplexTimeIdentifier |
Placeholder for a concrete vector. |
GenericDataIdentifier |
Placeholder for a concrete vector. |
MultiOperation1 |
A multi operation which holds a vector and records all changes
which need to be done to the vectors. By calling |
MultiOperation2 |
A multi operation which holds two vectors and records all changes
which need to be done to the vectors. By calling |
PreparedOperation1 |
An operation on one data vector which has been prepared in advance. |
PreparedOperation2 |
An operation on two data vectors which has been prepared in advance. |
RealFreqIdentifier |
Placeholder for a concrete vector. |
RealTimeIdentifier |
Placeholder for a concrete vector. |
Enums
Operation |
An alternative way to define operations on a vector. |
Traits
ComplexIdentifier |
Operations for complex vectors which can be used in combination
with multi ops or prepared ops. For a documentation of the specific operations
see |
GeneralIdentifier |
Operations for all kind of vectors which can be used in combination
with multi ops or prepared ops. For a documentation of the specific operations
see |
Identifier |
An identifier is just a placeholder for a vector used to ensure already at compile time that operations are valid. |
IdentifierIter |
Allows to map every vector element.
with multi ops or prepared ops. For a documentation of the specific operations
see |
Offset |
Offset operations to vectors in combination
with multi ops or prepared ops. For a documentation of the specific operations
see |
RealIdentifier |
Operations for real vectors which can be used on combination
with multi ops or prepared ops. For a documentation of the specific operations
see |
Scale |
Scale operations to vectors in combination
with multi ops or prepared ops. For a documentation of the specific operations
see |
ToIdentifier |
Trait which defines the relation between a vector and an identifier. |
Functions
multi_ops1 |
Creates a new multi operation for one vectors. |
multi_ops2 |
Creates a new multi operation for two vectors. |
prepare1 |
Prepares an operation with one input and one output. |
prepare2 |
Prepares an operation with two inputs and two outputs. |