Commit 5af1d475abf77f466a66bddaa70b339ea1ff1d65

Authored by Josh Cardenzana
1 parent 92543c1e

Change critical zones in GWcs::dir2pix and GWcs::pix2dir to remove critical regi…

…ons and replace with omp_locks
include/GWcs.hpp
... ... @@ -30,6 +30,7 @@
30 30 /* __ Includes ___________________________________________________________ */
31 31 #include <vector>
32 32 #include <string>
  33 +#include <map>
33 34 #include <iostream>
34 35 #include "GSkyProjection.hpp"
35 36 #include "GLog.hpp"
... ... @@ -37,6 +38,10 @@
37 38 #include "GSkyDir.hpp"
38 39 #include "GSkyPixel.hpp"
39 40  
  41 +#ifdef _OPENMP
  42 +#include <omp.h>
  43 +#endif
  44 +
40 45  
41 46 /***********************************************************************//**
42 47 * @class GWcs
... ... @@ -220,6 +225,15 @@ protected:
220 225 mutable GSkyDir m_last_dir2pix_dir; //!< Last sky direction for dir2pix
221 226 mutable GSkyPixel m_last_pix2dir_pix; //!< Last pixel for pix2dir
222 227 mutable GSkyPixel m_last_dir2pix_pix; //!< Last pixel for dir2pix
  228 +
  229 + // Thread locking
  230 + void init_lock(const int& lock_id=0) const;
  231 + void set_lock(const int& lock_id=0) const;
  232 + void unset_lock(const int& lock_id=0) const;
  233 +
  234 + #ifdef _OPENMP
  235 + mutable std::map<int, omp_lock_t> m_locks;
  236 + #endif
223 237 };
224 238  
225 239  
... ... @@ -236,4 +250,49 @@ int GWcs::size(void) const
236 250 return 2;
237 251 }
238 252  
  253 +
  254 +/***********************************************************************//**
  255 + * @brief Initializes an OpenMP lock with a specific name
  256 + *
  257 + * @param[in] lock_name Name of the lock that should be initialized
  258 + ***************************************************************************/
  259 +inline
  260 +void GWcs::init_lock(const int& lock_id) const
  261 +{
  262 + #ifdef _OPENMP
  263 + if (m_locks.count(lock_id) == 0) {
  264 + m_locks[lock_id] = omp_lock_t();
  265 + omp_init_lock(&m_locks[lock_id]);
  266 + }
  267 + #endif
  268 +}
  269 +
  270 +
  271 +/***********************************************************************//**
  272 + * @brief Sets an OpenMP lock with a specific name
  273 + *
  274 + * @param[in] lock_name Name of the lock that should be set
  275 + ***************************************************************************/
  276 +inline
  277 +void GWcs::set_lock(const int& lock_id) const
  278 +{
  279 + #ifdef _OPENMP
  280 + omp_set_lock(&m_locks[lock_id]);
  281 + #endif
  282 +}
  283 +
  284 +
  285 +/***********************************************************************//**
  286 + * @brief Releases a previously set OpenMP lock
  287 + *
  288 + * @param[in] lock_name Name of the lock to be released
  289 + ***************************************************************************/
  290 +inline
  291 +void GWcs::unset_lock(const int& lock_id) const
  292 +{
  293 + #ifdef _OPENMP
  294 + omp_unset_lock(&m_locks[lock_id]);
  295 + #endif
  296 +}
  297 +
239 298 #endif /* GWCS_HPP */
... ...
src/sky/GWcs.cpp
... ... @@ -678,13 +678,16 @@ GSkyDir GWcs::pix2dir(const GSkyPixel&amp; pixel) const
678 678 // the one used for the cache, then get the cached sky direction. We need
679 679 // to put this in a OMP critical zone so that no other thread will change
680 680 // the cache in the meantime
681   - #pragma omp critical(GWcs_pix2dir_1)
  681 + bool update_cache = true;
  682 + set_lock(2);
682 683 if (m_has_pix2dir_cache && (m_last_pix2dir_pix == pixel)) {
683 684 dir = m_last_pix2dir_dir;
  685 + update_cache = false;
684 686 }
  687 + unset_lock(2);
685 688  
686 689 // ... otherwise the computation of the sky direction is needed
687   - else {
  690 + if (update_cache) {
688 691  
689 692 // Allocate memory for transformation
690 693 double pixcrd[2];
... ... @@ -712,12 +715,13 @@ GSkyDir GWcs::pix2dir(const GSkyPixel&amp; pixel) const
712 715  
713 716 // Store result in cache. We need to put this in a OMP critical zone
714 717 // to make sure that no other thread is fiddeling with the cache
715   - #pragma omp critical(GWcs_pix2dir_2)
  718 + set_lock(2);
716 719 {
717 720 m_has_pix2dir_cache = true;
718 721 m_last_pix2dir_pix = pixel;
719 722 m_last_pix2dir_dir = dir;
720 723 }
  724 + unset_lock(2);
721 725  
722 726 // Debug: Dump transformation steps
723 727 #if defined(G_XY2DIR_DEBUG)
... ... @@ -758,13 +762,16 @@ GSkyPixel GWcs::dir2pix(const GSkyDir&amp; dir) const
758 762 // to the one used for the cache, then get the cached sky pixel. We need
759 763 // to put this in a OMP critical zone so that no other thread will change
760 764 // the cache in the meantime
761   - #pragma omp critical(GWcs_dir2pix_1)
  765 + bool update_cache = true;
  766 + set_lock(1);
762 767 if (m_has_dir2pix_cache && (m_last_dir2pix_dir == dir)) {
763 768 pixel = m_last_dir2pix_pix;
  769 + update_cache = false;
764 770 }
  771 + unset_lock(1);
765 772  
766 773 // ... otherwise the computation of the sky pixel is needed
767   - else {
  774 + if (update_cache) {
768 775  
769 776 // Allocate memory for transformation
770 777 double pixcrd[2];
... ... @@ -793,12 +800,13 @@ GSkyPixel GWcs::dir2pix(const GSkyDir&amp; dir) const
793 800  
794 801 // Store result in cache. We need to put this in a OMP critical zone
795 802 // to make sure that no other thread is fiddeling with the cache
796   - #pragma omp critical(GWcs_dir2pix_2)
  803 + set_lock(1);
797 804 {
798 805 m_has_dir2pix_cache = true;
799 806 m_last_dir2pix_dir = dir;
800 807 m_last_dir2pix_pix = pixel;
801 808 }
  809 + unset_lock(1);
802 810  
803 811 // Debug: Dump transformation steps
804 812 #if defined(G_DIR2XY_DEBUG)
... ... @@ -944,6 +952,12 @@ void GWcs::init_members(void)
944 952 m_last_pix2dir_pix.clear();
945 953 m_last_dir2pix_pix.clear();
946 954  
  955 + // Initialize the locks
  956 + #ifdef _OPENMP
  957 + init_lock(1);
  958 + init_lock(2);
  959 + #endif
  960 +
947 961 // Return
948 962 return;
949 963 }
... ...