aligned_memory.rs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. use std::{alloc::{alloc_zeroed, dealloc, Layout}, slice::{from_raw_parts, from_raw_parts_mut}, ops::{Index, IndexMut}, mem::size_of};
  2. const ALIGN_SIMD: usize = 64; // enough to support AVX-512
  3. pub type AlignedMemory64 = AlignedMemory<ALIGN_SIMD>;
  4. pub struct AlignedMemory<const ALIGN: usize> {
  5. p: *mut u64,
  6. sz_u64: usize,
  7. layout: Layout
  8. }
  9. impl<const ALIGN: usize> AlignedMemory<{ALIGN}> {
  10. pub fn new(sz_u64: usize) -> Self {
  11. let sz_bytes = sz_u64 * size_of::<u64>();
  12. let layout = Layout::from_size_align(sz_bytes, ALIGN).unwrap();
  13. let ptr;
  14. unsafe {
  15. ptr = alloc_zeroed(layout);
  16. }
  17. Self {
  18. p: ptr as *mut u64,
  19. sz_u64,
  20. layout
  21. }
  22. }
  23. pub fn as_slice(&self) -> &[u64] {
  24. unsafe {
  25. from_raw_parts(self.p, self.sz_u64)
  26. }
  27. }
  28. pub fn as_mut_slice(&mut self) -> &mut [u64] {
  29. unsafe {
  30. from_raw_parts_mut(self.p, self.sz_u64)
  31. }
  32. }
  33. pub fn len(&self) -> usize {
  34. self.sz_u64
  35. }
  36. }
  37. impl<const ALIGN: usize> Drop for AlignedMemory<{ALIGN}> {
  38. fn drop(&mut self) {
  39. unsafe {
  40. dealloc(self.p as *mut u8, self.layout);
  41. }
  42. }
  43. }
  44. impl<const ALIGN: usize> Index<usize> for AlignedMemory<{ALIGN}> {
  45. type Output = u64;
  46. fn index(&self, index: usize) -> &Self::Output {
  47. &self.as_slice()[index]
  48. }
  49. }
  50. impl<const ALIGN: usize> IndexMut<usize> for AlignedMemory<{ALIGN}> {
  51. fn index_mut(&mut self, index: usize) -> &mut Self::Output {
  52. &mut self.as_mut_slice()[index]
  53. }
  54. }
  55. impl<const ALIGN: usize> Clone for AlignedMemory<{ALIGN}> {
  56. fn clone(&self) -> Self {
  57. let mut out = Self::new(self.sz_u64);
  58. out.as_mut_slice().copy_from_slice(self.as_slice());
  59. out
  60. }
  61. }