aligned_memory.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. use std::{
  2. alloc::{alloc_zeroed, dealloc, Layout},
  3. mem::size_of,
  4. ops::{Index, IndexMut},
  5. slice::{from_raw_parts, from_raw_parts_mut},
  6. };
  7. const ALIGN_SIMD: usize = 64; // enough to support AVX-512
  8. pub type AlignedMemory64 = AlignedMemory<ALIGN_SIMD>;
  9. pub struct AlignedMemory<const ALIGN: usize> {
  10. p: *mut u64,
  11. sz_u64: usize,
  12. layout: Layout,
  13. }
  14. impl<const ALIGN: usize> AlignedMemory<{ ALIGN }> {
  15. pub fn new(sz_u64: usize) -> Self {
  16. let sz_bytes = sz_u64 * size_of::<u64>();
  17. let layout = Layout::from_size_align(sz_bytes, ALIGN).unwrap();
  18. let ptr;
  19. unsafe {
  20. ptr = alloc_zeroed(layout);
  21. }
  22. Self {
  23. p: ptr as *mut u64,
  24. sz_u64,
  25. layout,
  26. }
  27. }
  28. // pub fn from(data: &[u8]) -> Self {
  29. // let sz_u64 = (data.len() + size_of::<u64>() - 1) / size_of::<u64>();
  30. // let mut out = Self::new(sz_u64);
  31. // let out_slice = out.as_mut_slice();
  32. // let mut i = 0;
  33. // for chunk in data.chunks(size_of::<u64>()) {
  34. // out_slice[i] = u64::from_ne_bytes(chunk);
  35. // i += 1;
  36. // }
  37. // out
  38. // }
  39. pub fn as_slice(&self) -> &[u64] {
  40. unsafe { from_raw_parts(self.p, self.sz_u64) }
  41. }
  42. pub fn as_mut_slice(&mut self) -> &mut [u64] {
  43. unsafe { from_raw_parts_mut(self.p, self.sz_u64) }
  44. }
  45. pub unsafe fn as_ptr(&self) -> *const u64 {
  46. self.p
  47. }
  48. pub unsafe fn as_mut_ptr(&mut self) -> *mut u64 {
  49. self.p
  50. }
  51. pub fn len(&self) -> usize {
  52. self.sz_u64
  53. }
  54. }
  55. unsafe impl<const ALIGN: usize> Send for AlignedMemory<{ ALIGN }> {}
  56. unsafe impl<const ALIGN: usize> Sync for AlignedMemory<{ ALIGN }> {}
  57. impl<const ALIGN: usize> Drop for AlignedMemory<{ ALIGN }> {
  58. fn drop(&mut self) {
  59. unsafe {
  60. dealloc(self.p as *mut u8, self.layout);
  61. }
  62. }
  63. }
  64. impl<const ALIGN: usize> Index<usize> for AlignedMemory<{ ALIGN }> {
  65. type Output = u64;
  66. fn index(&self, index: usize) -> &Self::Output {
  67. &self.as_slice()[index]
  68. }
  69. }
  70. impl<const ALIGN: usize> IndexMut<usize> for AlignedMemory<{ ALIGN }> {
  71. fn index_mut(&mut self, index: usize) -> &mut Self::Output {
  72. &mut self.as_mut_slice()[index]
  73. }
  74. }
  75. impl<const ALIGN: usize> Clone for AlignedMemory<{ ALIGN }> {
  76. fn clone(&self) -> Self {
  77. let mut out = Self::new(self.sz_u64);
  78. out.as_mut_slice().copy_from_slice(self.as_slice());
  79. out
  80. }
  81. }