From 2e466792e996a82a5fceffc77b0b6652fa7f5b0f Mon Sep 17 00:00:00 2001 From: conrad Date: Fri, 7 Oct 2022 00:07:22 +1000 Subject: [PATCH] simplification: use std::atomic directly on mat pointers --- include/armadillo_bits/Cube_bones.hpp | 26 ++++-- include/armadillo_bits/Cube_meat.hpp | 103 ++++++------------------ include/armadillo_bits/arma_forward.hpp | 9 --- 3 files changed, 44 insertions(+), 94 deletions(-) diff --git a/include/armadillo_bits/Cube_bones.hpp b/include/armadillo_bits/Cube_bones.hpp index f29140d5..2a04f271 100644 --- a/include/armadillo_bits/Cube_bones.hpp +++ b/include/armadillo_bits/Cube_bones.hpp @@ -60,13 +60,24 @@ class Cube : public BaseCube< eT, Cube > #if (!defined(ARMA_DONT_USE_STD_MUTEX)) mutable std::mutex mat_mutex; #endif + + using mat_type = Mat; - Mat** 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; + #else + using raw_mat_ptr_type = mat_type*; + using atomic_mat_ptr_type = mat_type*; + #endif - arma_align_mem Mat* 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::fixed : public Cube static constexpr bool use_extra = (fixed_n_elem > Cube_prealloc::mem_n_elem); - arma_aligned Mat* 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(); diff --git a/include/armadillo_bits/Cube_meat.hpp b/include/armadillo_bits/Cube_meat.hpp index 840b69f5..05278f58 100644 --- a/include/armadillo_bits/Cube_meat.hpp +++ b/include/armadillo_bits/Cube_meat.hpp @@ -531,10 +531,12 @@ Cube::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::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::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*[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::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('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('j', mat_mem, n_rows, n_cols); } @@ -636,66 +607,53 @@ Cube::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::steal_mem(Cube& 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::fixed::mem_setup() access::rw(Cube::mem_state) = 3; access::rw(Cube::mem) = (fixed_n_elem > Cube_prealloc::mem_n_elem) ? mem_local_extra : mem_local; Cube::mat_ptrs = (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local; - Cube::mat_flag = (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_flag_local_extra : mat_flag_local; create_mat(); } @@ -5406,7 +5356,6 @@ Cube::fixed::mem_setup() access::rw(Cube::mem_state) = 3; access::rw(Cube::mem) = nullptr; Cube::mat_ptrs = nullptr; - Cube::mat_flag = nullptr; } } diff --git a/include/armadillo_bits/arma_forward.hpp b/include/armadillo_bits/arma_forward.hpp index e6120c02..8b2f15d3 100644 --- a/include/armadillo_bits/arma_forward.hpp +++ b/include/armadillo_bits/arma_forward.hpp @@ -270,15 +270,6 @@ template struct unwrap_spmat; -#if defined(ARMA_USE_OPENMP) - typedef bool arma_atomic_bool; -#elif (!defined(ARMA_DONT_USE_STD_MUTEX)) - typedef std::atomic arma_atomic_bool; -#else - typedef bool arma_atomic_bool; -#endif - - struct state_type {