simplification: use std::atomic directly on mat pointers

This commit is contained in:
conrad
2022-10-07 00:07:22 +10:00
parent 5dff1abc12
commit 2e466792e9
3 changed files with 44 additions and 94 deletions
+18 -8
View File
@@ -60,13 +60,24 @@ class Cube : public BaseCube< eT, Cube<eT> >
#if (!defined(ARMA_DONT_USE_STD_MUTEX))
mutable std::mutex mat_mutex;
#endif
using mat_type = Mat<eT>;
Mat<eT>** mat_ptrs = nullptr;
arma_atomic_bool* mat_flag = nullptr;
#if defined(ARMA_USE_OPENMP)
using raw_mat_ptr_type = mat_type*;
using atomic_mat_ptr_type = mat_type*;
#elif (!defined(ARMA_DONT_USE_STD_MUTEX))
using raw_mat_ptr_type = mat_type*;
using atomic_mat_ptr_type = std::atomic<mat_type*>;
#else
using raw_mat_ptr_type = mat_type*;
using atomic_mat_ptr_type = mat_type*;
#endif
arma_align_mem Mat<eT>* mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ];
arma_align_mem arma_atomic_bool mat_flag_local[ Cube_prealloc::mat_ptrs_size ];
arma_align_mem eT mem_local[ Cube_prealloc::mem_n_elem ]; // local storage, for small cubes
atomic_mat_ptr_type* mat_ptrs = nullptr;
arma_align_mem atomic_mat_ptr_type mat_ptrs_local[ Cube_prealloc::mat_ptrs_size ];
arma_align_mem eT mem_local[ Cube_prealloc::mem_n_elem ]; // local storage, for small cubes
public:
@@ -480,9 +491,8 @@ class Cube<eT>::fixed : public Cube<eT>
static constexpr bool use_extra = (fixed_n_elem > Cube_prealloc::mem_n_elem);
arma_aligned Mat<eT>* mat_ptrs_local_extra[ (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? fixed_n_slices : 1 ];
arma_aligned arma_atomic_bool mat_flag_local_extra[ (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? fixed_n_slices : 1 ];
arma_align_mem eT mem_local_extra[ use_extra ? fixed_n_elem : 1 ];
arma_aligned atomic_mat_ptr_type mat_ptrs_local_extra[ (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? fixed_n_slices : 1 ];
arma_align_mem eT mem_local_extra[ use_extra ? fixed_n_elem : 1 ];
arma_inline void mem_setup();
+26 -77
View File
@@ -531,10 +531,12 @@ Cube<eT>::delete_mat()
{
for(uword s=0; s < n_slices; ++s)
{
if(mat_ptrs[s] != nullptr)
raw_mat_ptr_type mat_ptr = raw_mat_ptr_type(mat_ptrs[s]);
if(mat_ptr != nullptr)
{
arma_extra_debug_print( arma_str::format("Cube::delete_mat(): destroying matrix %d") % s );
delete mat_ptrs[s];
delete mat_ptr;
mat_ptrs[s] = nullptr;
}
}
@@ -546,18 +548,6 @@ Cube<eT>::delete_mat()
mat_ptrs = nullptr;
}
}
if(mat_flag != nullptr)
{
for(uword s=0; s < n_slices; ++s) { mat_flag[s] = false; }
if( (mem_state <= 2) && (n_slices > Cube_prealloc::mat_ptrs_size) )
{
arma_extra_debug_print("Cube::delete_mat(): freeing mat_flag array");
delete [] mat_flag;
mat_flag = nullptr;
}
}
}
@@ -569,44 +559,27 @@ Cube<eT>::create_mat()
{
arma_extra_debug_sigprint();
if(n_slices == 0)
{
mat_ptrs = nullptr;
mat_flag = nullptr;
return;
}
if(n_slices == 0) { mat_ptrs = nullptr; return; }
if(mem_state <= 2)
{
if(n_slices <= Cube_prealloc::mat_ptrs_size)
{
arma_extra_debug_print("Cube::create_mat(): using local memory for mat_ptrs and mat_flag arrays");
arma_extra_debug_print("Cube::create_mat(): using local memory for mat_ptrs array");
mat_ptrs = mat_ptrs_local;
mat_flag = mat_flag_local;
}
else
{
arma_extra_debug_print("Cube::create_mat(): allocating mat_ptrs array");
mat_ptrs = new(std::nothrow) Mat<eT>*[n_slices];
mat_ptrs = new(std::nothrow) atomic_mat_ptr_type[n_slices];
arma_check_bad_alloc( (mat_ptrs == nullptr), "Cube::create_mat(): out of memory" );
arma_extra_debug_print("Cube::create_mat(): allocating mat_flag array");
mat_flag = new(std::nothrow) arma_atomic_bool[n_slices];
arma_check_bad_alloc( (mat_flag == nullptr), "Cube::create_mat(): out of memory" );
}
}
for(uword s=0; s < n_slices; ++s)
{
mat_ptrs[s] = nullptr;
mat_flag[s] = false;
}
for(uword s=0; s < n_slices; ++s) { mat_ptrs[s] = nullptr; }
}
@@ -618,13 +591,11 @@ Cube<eT>::create_mat_ptr(const uword in_slice) const
{
arma_extra_debug_sigprint();
if(mat_ptrs[in_slice] != nullptr) { return; }
const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr;
arma_extra_debug_print( arma_str::format("Cube::create_mat_ptr(): creating matrix %d") % in_slice );
mat_ptrs[in_slice] = new Mat<eT>('j', ptr, n_rows, n_cols);
const eT* mat_mem = (n_elem_slice > 0) ? slice_memptr(in_slice) : nullptr;
mat_ptrs[in_slice] = new Mat<eT>('j', mat_mem, n_rows, n_cols);
}
@@ -636,66 +607,53 @@ Cube<eT>::get_mat_ptr(const uword in_slice) const
{
arma_extra_debug_sigprint();
bool flag = false;
raw_mat_ptr_type mat_ptr = nullptr;
#if defined(ARMA_USE_OPENMP)
{
#pragma omp atomic read
flag = mat_flag[in_slice];
mat_ptr = mat_ptrs[in_slice];
}
#elif (!defined(ARMA_DONT_USE_STD_MUTEX))
{
flag = mat_flag[in_slice].load();
mat_ptr = mat_ptrs[in_slice].load();
}
#else
{
flag = mat_flag[in_slice];
mat_ptr = mat_ptrs[in_slice];
}
#endif
if(flag == false)
if(mat_ptr == nullptr)
{
#if defined(ARMA_USE_OPENMP)
{
#pragma omp critical (arma_Cube_mat_ptrs)
{
#pragma omp atomic read
flag = mat_flag[in_slice];
mat_ptr = mat_ptrs[in_slice];
if(flag == false)
{
create_mat_ptr(in_slice);
#pragma omp atomic write
mat_flag[in_slice] = true;
}
if(mat_ptr == nullptr) { create_mat_ptr(in_slice); }
}
}
#elif (!defined(ARMA_DONT_USE_STD_MUTEX))
{
mat_mutex.lock();
flag = mat_flag[in_slice].load();
mat_ptr = mat_ptrs[in_slice].load();
if(flag == false)
{
create_mat_ptr(in_slice);
mat_flag[in_slice].store(true);
}
if(mat_ptr == nullptr) { create_mat_ptr(in_slice); }
mat_mutex.unlock();
}
#else
{
create_mat_ptr(in_slice);
mat_flag[in_slice] = true;
}
#endif
}
return mat_ptrs[in_slice];
return raw_mat_ptr_type(mat_ptrs[in_slice]);
}
@@ -5318,28 +5276,21 @@ Cube<eT>::steal_mem(Cube<eT>& x, const bool is_move)
if(x_n_slices > Cube_prealloc::mat_ptrs_size)
{
arma_extra_debug_print("Cube::steal_mem(): stealing mat_ptrs and mat_flag arrays");
mat_ptrs = x.mat_ptrs;
mat_flag = x.mat_flag;
arma_extra_debug_print("Cube::steal_mem(): stealing mat_ptrs array");
mat_ptrs = x.mat_ptrs;
x.mat_ptrs = nullptr;
x.mat_flag = nullptr;
}
else
{
arma_extra_debug_print("Cube::steal_mem(): copying mat_ptrs and mat_flag arrays");
arma_extra_debug_print("Cube::steal_mem(): copying mat_ptrs array");
mat_ptrs = mat_ptrs_local;
mat_flag = mat_flag_local;
for(uword i=0; i < x_n_slices; ++i)
{
mat_ptrs[i] = x.mat_ptrs[i];
mat_flag[i] = bool(x.mat_flag[i]);
mat_ptrs[i] = raw_mat_ptr_type(x.mat_ptrs[i]);
x.mat_ptrs[i] = nullptr;
x.mat_flag[i] = false;
}
}
@@ -5391,7 +5342,6 @@ Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::mem_setup()
access::rw(Cube<eT>::mem_state) = 3;
access::rw(Cube<eT>::mem) = (fixed_n_elem > Cube_prealloc::mem_n_elem) ? mem_local_extra : mem_local;
Cube<eT>::mat_ptrs = (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local;
Cube<eT>::mat_flag = (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_flag_local_extra : mat_flag_local;
create_mat();
}
@@ -5406,7 +5356,6 @@ Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::mem_setup()
access::rw(Cube<eT>::mem_state) = 3;
access::rw(Cube<eT>::mem) = nullptr;
Cube<eT>::mat_ptrs = nullptr;
Cube<eT>::mat_flag = nullptr;
}
}
-9
View File
@@ -270,15 +270,6 @@ template<typename T1> struct unwrap_spmat;
#if defined(ARMA_USE_OPENMP)
typedef bool arma_atomic_bool;
#elif (!defined(ARMA_DONT_USE_STD_MUTEX))
typedef std::atomic<bool> arma_atomic_bool;
#else
typedef bool arma_atomic_bool;
#endif
struct state_type
{