Audacity 3.2.0
Classes | Functions
staffpad::audio::simd Namespace Reference

Classes

struct  float_x4
 

Functions

void * aligned_malloc (size_t required_bytes, size_t alignment)
 reserve aligned memory. Needs to be freed with aligned_free() More...
 
void aligned_free (void *p)
 free memory allocated with aligned_malloc More...
 
template<typename cls >
cls * aligned_new (int alignment)
 create a c++ class at an memory-aligned spot that needs to be deleted using aligned_delete More...
 
template<typename cls >
void aligned_delete (cls *obj)
 
template<typename T >
bool is_aligned (T *obj, int alignment)
 
template<typename fnc >
__finl void perform_parallel_simd_aligned (float *a, float *b, int n, const fnc &f)
 
template<typename fnc >
__finl void perform_parallel_simd_aligned (float *a, int n, const fnc &f)
 template for applying math to one data buffer More...
 
__finl float_x4 __vecc float_x4_from_float (float x)
 
__finl float_x4 __vecc float_x4_load_aligned (const float *x)
 
__finl void __vecc store_aligned (const float_x4 &a, float *x)
 
__finl float_x4 __vecc unzip1 (const float_x4 &a, const float_x4 &b)
 
__finl float_x4 __vecc unzip2 (const float_x4 &a, const float_x4 &b)
 
__finl float_x4 __vecc operator+ (float_x4 a, float_x4 b)
 
__finl float_x4 __vecc operator- (float_x4 a, float_x4 b)
 
__finl float_x4 __vecc operator* (float_x4 a, float_x4 b)
 
__finl float_x4 __vecc sqrt (const float_x4 &a)
 
__finl float __vecc rint (float a)
 
__finl float_x4 __vecc rint (const float_x4 &a)
 

Function Documentation

◆ aligned_delete()

template<typename cls >
void staffpad::audio::simd::aligned_delete ( cls *  obj)
inline

delete objects created using aligned_new

Definition at line 59 of file SimdTypes.h.

60{
61 if (obj != nullptr)
62 {
63 obj->~cls();
64 aligned_free((void *)obj);
65 }
66}
void aligned_free(void *p)
free memory allocated with aligned_malloc
Definition: SimdTypes.h:43

References aligned_free().

Here is the call graph for this function:

◆ aligned_free()

void staffpad::audio::simd::aligned_free ( void *  p)
inline

free memory allocated with aligned_malloc

Definition at line 43 of file SimdTypes.h.

44{
45 if (p)
46 free(((void **)p)[-1]);
47}
void free(void *ptr)
Definition: VectorOps.h:34

References staffpad::vo::free().

Referenced by aligned_delete(), and staffpad::SamplesFloat< T >::dealloc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ aligned_malloc()

void * staffpad::audio::simd::aligned_malloc ( size_t  required_bytes,
size_t  alignment 
)
inline

reserve aligned memory. Needs to be freed with aligned_free()

Definition at line 29 of file SimdTypes.h.

30{
31 auto offset = alignment - 1 + sizeof(void *);
32 auto p1 = std::malloc(required_bytes + offset);
33 if (p1 == nullptr)
34 return nullptr;
35 // figure out aligned position
36 void *p2 = (void *)(((size_t)(p1) + offset) & ~(alignment - 1));
37 // write malloced pointer in front of aligned data
38 ((void **)p2)[-1] = p1;
39 return p2;
40}

Referenced by aligned_new(), and staffpad::SamplesFloat< T >::alloc().

Here is the caller graph for this function:

◆ aligned_new()

template<typename cls >
cls * staffpad::audio::simd::aligned_new ( int  alignment)
inline

create a c++ class at an memory-aligned spot that needs to be deleted using aligned_delete

Definition at line 51 of file SimdTypes.h.

52{
53 void *mem = aligned_malloc(sizeof(cls), alignment);
54 return new (mem) cls();
55}
void * aligned_malloc(size_t required_bytes, size_t alignment)
reserve aligned memory. Needs to be freed with aligned_free()
Definition: SimdTypes.h:29

References aligned_malloc().

Here is the call graph for this function:

◆ float_x4_from_float()

__finl float_x4 __vecc staffpad::audio::simd::float_x4_from_float ( float  x)

Definition at line 104 of file SimdTypes_neon.h.

105{
106 return vdupq_n_f32(x);
107}

◆ float_x4_load_aligned()

__finl float_x4 __vecc staffpad::audio::simd::float_x4_load_aligned ( const float *  x)

Definition at line 109 of file SimdTypes_neon.h.

110{
111 return vld1q_f32(x);
112}

Referenced by perform_parallel_simd_aligned().

Here is the caller graph for this function:

◆ is_aligned()

template<typename T >
bool staffpad::audio::simd::is_aligned ( T *  obj,
int  alignment 
)
inline

Definition at line 69 of file SimdTypes.h.

70{
71 return (((size_t)obj) & (alignment - 1)) == 0;
72}

Referenced by perform_parallel_simd_aligned().

Here is the caller graph for this function:

◆ operator*()

__finl float_x4 __vecc staffpad::audio::simd::operator* ( float_x4  a,
float_x4  b 
)

Definition at line 139 of file SimdTypes_neon.h.

140{
141 return vmulq_f32(a.s, b.s);
142}

References staffpad::audio::simd::float_x4::s.

◆ operator+()

__finl float_x4 __vecc staffpad::audio::simd::operator+ ( float_x4  a,
float_x4  b 
)

Definition at line 129 of file SimdTypes_neon.h.

130{
131 return vaddq_f32(a.s, b.s);
132}

References staffpad::audio::simd::float_x4::s.

◆ operator-()

__finl float_x4 __vecc staffpad::audio::simd::operator- ( float_x4  a,
float_x4  b 
)

Definition at line 134 of file SimdTypes_neon.h.

135{
136 return vsubq_f32(a.s, b.s);
137}

References staffpad::audio::simd::float_x4::s.

◆ perform_parallel_simd_aligned() [1/2]

template<typename fnc >
__finl void staffpad::audio::simd::perform_parallel_simd_aligned ( float *  a,
float *  b,
int  n,
const fnc &  f 
)

this template allows to write float SIMD code with the supported operators the following way:

float *a_vec; const float *b_vec; perform_parallel_simd_aligned(a_vec, b_vec, 512, [](auto &a, auto &b) { auto t = a; a = 3.f * a + 12.f * b; b = 0.25f * a + 3.f * b; });

Definition at line 87 of file SimdTypes.h.

88{
89 // fnc& f needs to be a lambda of type [](auto &a, auto &b){}.
90 // the autos will be float_x4/float
91 constexpr int N = 4;
92 constexpr int byte_size = sizeof(float);
93
94 assert(is_aligned(a, N * byte_size) && is_aligned(b, N * byte_size));
95
96 for (int i = 0; i <= n - N; i += N)
97 {
98 auto x = float_x4_load_aligned(a + i);
99 auto y = float_x4_load_aligned(b + i);
100 f(x, y);
101 store_aligned(x, a + i);
102 store_aligned(y, b + i);
103 }
104 // deal with last partial packet
105 for (int i = n & (~(N - 1)); i < n; ++i)
106 f(a[i], b[i]);
107}
bool is_aligned(T *obj, int alignment)
Definition: SimdTypes.h:69
__finl float_x4 __vecc float_x4_load_aligned(const float *x)
__finl void __vecc store_aligned(const float_x4 &a, float *x)

References float_x4_load_aligned(), is_aligned(), and store_aligned().

Referenced by staffpad::anonymous_namespace{TimeAndPitch.cpp}::_fft_shift(), staffpad::anonymous_namespace{TimeAndPitch.cpp}::_lr_to_ms(), staffpad::anonymous_namespace{TimeAndPitch.cpp}::_ms_to_lr(), and staffpad::anonymous_namespace{TimeAndPitch.cpp}::_unwrapPhaseVec().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ perform_parallel_simd_aligned() [2/2]

template<typename fnc >
__finl void staffpad::audio::simd::perform_parallel_simd_aligned ( float *  a,
int  n,
const fnc &  f 
)

template for applying math to one data buffer

Definition at line 111 of file SimdTypes.h.

112{
113 // fnc& f needs to be a lambda of type [](auto &a){}.
114 constexpr int N = 4;
115 constexpr int byte_size = sizeof(float);
116 assert(is_aligned(a, N * byte_size));
117
118 for (int i = 0; i <= n - N; i += N)
119 {
120 auto x = float_x4_load_aligned(a + i);
121 f(x);
122 store_aligned(x, a + i);
123 }
124 // deal with last partial packet
125 for (int i = n & (~(N - 1)); i < n; ++i)
126 f(a[i]);
127}

References float_x4_load_aligned(), is_aligned(), and store_aligned().

Here is the call graph for this function:

◆ rint() [1/2]

__finl float_x4 __vecc staffpad::audio::simd::rint ( const float_x4 a)

Definition at line 154 of file SimdTypes_neon.h.

155{
156 return vrndnq_f32(a.s);
157}

References staffpad::audio::simd::float_x4::s.

Referenced by rint().

Here is the caller graph for this function:

◆ rint() [2/2]

__finl float __vecc staffpad::audio::simd::rint ( float  a)

Definition at line 149 of file SimdTypes_neon.h.

150{
151 return std::rint(a);
152}
__finl float_x4 __vecc rint(const float_x4 &a)

References rint().

Referenced by staffpad::anonymous_namespace{TimeAndPitch.cpp}::_unwrapPhase(), staffpad::anonymous_namespace{TimeAndPitch.cpp}::_unwrapPhaseVec(), WaveTrackShifter::HintOffsetLarger(), WaveTrackShifter::QuantizeOffset(), and LWSlider::ValueToPosition().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sqrt()

__finl float_x4 __vecc staffpad::audio::simd::sqrt ( const float_x4 a)

◆ store_aligned()

__finl void __vecc staffpad::audio::simd::store_aligned ( const float_x4 a,
float *  x 
)

Definition at line 114 of file SimdTypes_neon.h.

115{
116 vst1q_f32(x, a.s);
117}

References staffpad::audio::simd::float_x4::s.

Referenced by perform_parallel_simd_aligned().

Here is the caller graph for this function:

◆ unzip1()

__finl float_x4 __vecc staffpad::audio::simd::unzip1 ( const float_x4 a,
const float_x4 b 
)

Definition at line 119 of file SimdTypes_neon.h.

120{
121 return vuzp1q_f32(a.s, b.s);
122}

References staffpad::audio::simd::float_x4::s.

◆ unzip2()

__finl float_x4 __vecc staffpad::audio::simd::unzip2 ( const float_x4 a,
const float_x4 b 
)

Definition at line 124 of file SimdTypes_neon.h.

125{
126 return vuzp2q_f32(a.s, b.s);
127}

References staffpad::audio::simd::float_x4::s.