fork download
  1. use std::arch::x86_64::{
  2. _mm_loadu_si128, _mm_storeu_si128, _mm_min_epi32, _mm_max_epi32, _mm_shuffle_epi32
  3. };
  4. use std::fmt::Debug;
  5.  
  6. const N: usize = 5;
  7.  
  8. #[target_feature(enable = "sse2")]
  9. unsafe fn simd_sort5(arr: &mut [i32; N]) {
  10. // SIMDレジスタに4つの値をロード
  11. let mut v = _mm_loadu_si128(arr.as_ptr() as *const _);
  12.  
  13. // ステップ1: 各ペアでmin/maxを取得
  14. for _ in 0..4 {
  15. let v1 = _mm_shuffle_epi32(v, 0b10110001); // 比較 (0,1), (2,3)
  16. let v2 = _mm_shuffle_epi32(v, 0b11011000); // 比較 (0,2), (1,3)
  17. let v3 = _mm_shuffle_epi32(v, 0b11101110); // 比較 (0,3)
  18.  
  19. let min1 = _mm_min_epi32(v, v1);
  20. let max1 = _mm_max_epi32(v, v1);
  21.  
  22. let min2 = _mm_min_epi32(min1, v2);
  23. let max2 = _mm_max_epi32(max1, v2);
  24.  
  25. let min3 = _mm_min_epi32(min2, v3);
  26. let max3 = _mm_max_epi32(max2, v3);
  27.  
  28. v = _mm_shuffle_epi32(min3, 0b01000100);
  29. }
  30.  
  31. _mm_storeu_si128(arr.as_mut_ptr() as *mut _, v);
  32.  
  33. // SIMD処理後の配列の状態を確認 (デバッグ用)
  34. println!("{:?}", arr);
  35.  
  36. // 最後の要素を適切な位置に挿入
  37. let last = arr[4];
  38. let mut i = 3;
  39. while i >= 0 && arr[i] > last {
  40. arr[i + 1] = arr[i];
  41. i -= 1;
  42. }
  43. arr[i + 1] = last;
  44.  
  45. // 最終的なソート結果を出力
  46. println!("{:?}", arr);
  47. }
  48.  
  49. fn main() {
  50. let mut arr: [i32; 5] = [5, 2, 4, 1, 3];
  51. unsafe {
  52. simd_sort5(&mut arr);
  53. }
  54. }
  55.  
Success #stdin #stdout 0.01s 5284KB
stdin
Standard input is empty
stdout
[1, 1, 1, 1, 3]
[1, 1, 1, 1, 3]