vector.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #include "default.h"
  17. namespace embree
  18. {
  19. /*! invokes the memory monitor callback */
  20. struct MemoryMonitorInterface {
  21. virtual void memoryMonitor(ssize_t bytes, bool post) = 0;
  22. };
  23. /*! allocator that performs aligned monitored allocations */
  24. template<typename T, size_t alignment = 64>
  25. struct aligned_monitored_allocator
  26. {
  27. typedef T value_type;
  28. typedef T* pointer;
  29. typedef const T* const_pointer;
  30. typedef T& reference;
  31. typedef const T& const_reference;
  32. typedef std::size_t size_type;
  33. typedef std::ptrdiff_t difference_type;
  34. __forceinline aligned_monitored_allocator(MemoryMonitorInterface* device)
  35. : device(device) {}
  36. __forceinline pointer allocate( size_type n )
  37. {
  38. if (n) {
  39. assert(device);
  40. device->memoryMonitor(n*sizeof(T),false);
  41. }
  42. #if defined(__LINUX__) && defined(__AVX512ER__) // KNL
  43. if (n*sizeof(value_type) >= 14 * PAGE_SIZE_2M)
  44. {
  45. pointer p = (pointer) os_malloc(n*sizeof(value_type));
  46. assert(p);
  47. return p;
  48. }
  49. #endif
  50. return (pointer) alignedMalloc(n*sizeof(value_type),alignment);
  51. }
  52. __forceinline void deallocate( pointer p, size_type n )
  53. {
  54. if (p)
  55. {
  56. #if defined(__LINUX__) && defined(__AVX512ER__) // KNL
  57. if (n*sizeof(value_type) >= 14 * PAGE_SIZE_2M)
  58. os_free(p,n*sizeof(value_type));
  59. else
  60. alignedFree(p);
  61. #else
  62. alignedFree(p);
  63. #endif
  64. }
  65. else assert(n == 0);
  66. if (n) {
  67. assert(device);
  68. device->memoryMonitor(-ssize_t(n)*sizeof(T),true);
  69. }
  70. }
  71. __forceinline void construct( pointer p, const_reference val ) {
  72. new (p) T(val);
  73. }
  74. __forceinline void destroy( pointer p ) {
  75. p->~T();
  76. }
  77. private:
  78. MemoryMonitorInterface* device;
  79. };
  80. }
  81. /*! instantiate vector using monitored aligned allocations */
  82. #define VECTOR_INIT_ALLOCATOR
  83. #define vector_t mvector
  84. #define allocator_t aligned_monitored_allocator<T,std::alignment_of<T>::value>
  85. #include "../common/sys/vector_t.h"
  86. #undef vector_t
  87. #undef allocator_t
  88. #undef VECTOR_INIT_ALLOCATOR
  89. namespace embree
  90. {
  91. /*! monitored vector */
  92. //template<typename T> // FIXME: unfortunately not supported in VS2012
  93. //using mvector = vector_t<T,aligned_monitored_allocator<T,std::alignment_of<T>::value> >;
  94. }