Skip to content

Commit e3cb49b

Browse files
committed
kernel memcpy, updated example
1 parent 5a54abe commit e3cb49b

File tree

3 files changed

+109
-62
lines changed

3 files changed

+109
-62
lines changed

examples/memcpy_bench/src/main.rs

Lines changed: 79 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
#![no_std]
22
#![no_main]
33

4-
psp::module!("sample_module", 1, 1);
54
extern crate alloc;
65
use alloc::alloc::Layout;
6+
use alloc::format;
77
use core::time::Duration;
8+
use core::ffi::c_void;
9+
use psp::sys::SceUid;
10+
11+
psp::module!("sample_module", 1, 1);
812

913
fn psp_main() {
1014
psp::enable_home_button();
@@ -15,49 +19,80 @@ fn psp_main() {
1519
sys::sceKernelChangeCurrentThreadAttr(0, ThreadAttributes::VFPU);
1620
}
1721

18-
let size = 16;
19-
let iterations = 1000;
20-
let cpu_dur: Duration;
21-
let cpu32_dur: Duration;
22-
let dmac_dur: Duration;
23-
let vfpu_dur: Duration;
24-
25-
let src = unsafe { alloc::alloc::alloc(Layout::from_size_align_unchecked(size, 16)) };
26-
let dst = unsafe { alloc::alloc::alloc(Layout::from_size_align_unchecked(size, 16)) };
27-
cpu_dur = psp::benchmark(|| {
28-
for _ in 0..iterations {
29-
unsafe { memcpy(dst, src as *const u8, size); }
30-
}
31-
}, 10);
32-
33-
cpu32_dur = psp::benchmark(|| {
34-
for _ in 0..iterations {
35-
unsafe { memcpy32(dst, src as *const u8, size); }
36-
}
37-
}, 10);
38-
39-
40-
dmac_dur = psp::benchmark(|| {
41-
for _ in 0..iterations {
42-
unsafe { psp::sys::sceDmacMemcpy(dst, src as *const u8, size); }
43-
}
44-
}, 10);
45-
46-
vfpu_dur = psp::benchmark(|| {
47-
for _ in 0..iterations {
48-
unsafe { psp::sys::sceVfpuMemcpy(dst, src as *const u8, size); }
49-
}
50-
}, 10);
51-
52-
unsafe { alloc::alloc::dealloc(src, Layout::from_size_align_unchecked(size, 16)); }
53-
unsafe { alloc::alloc::dealloc(dst, Layout::from_size_align_unchecked(size, 16)); }
54-
55-
psp::dprintln!("size: {} bytes", size);
56-
psp::dprintln!("iterations: {}", iterations);
57-
psp::dprintln!("cpu: {} microseconds", cpu_dur.as_micros());
58-
psp::dprintln!("cpu32: {} microseconds", cpu32_dur.as_micros());
59-
psp::dprintln!("dmac: {} microseconds", dmac_dur.as_micros());
60-
psp::dprintln!("vfpu: {} microseconds", vfpu_dur.as_micros());
22+
let iters: [usize; 11] = [16, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1];
23+
let sizes: [usize; 11] = [32,64,512,1024,2048,16348,32768,65536,131072,524288,1048576];
24+
25+
let mut cpu_dur: Duration;
26+
let mut cpu32_dur: Duration;
27+
let mut kernel_dur: Duration;
28+
let mut dmac_dur: Duration;
29+
let mut vfpu_dur: Duration;
30+
31+
let fd = unsafe { psp::sys::sceIoOpen(b"host0:/results.txt\0".as_ptr(), psp::sys::IoOpenFlags::CREAT | psp::sys::IoOpenFlags::RD_WR, 0o777) };
32+
33+
for i in 0..11 {
34+
let size = sizes[i];
35+
let iterations = iters[i];
36+
let src = unsafe { alloc::alloc::alloc(Layout::from_size_align_unchecked(size, 16)) };
37+
let dst = unsafe { alloc::alloc::alloc(Layout::from_size_align_unchecked(size, 16)) };
38+
cpu_dur = psp::benchmark(|| {
39+
for _ in 0..iterations {
40+
unsafe { memcpy(dst, src as *const u8, size); }
41+
}
42+
}, 10);
43+
44+
cpu32_dur = psp::benchmark(|| {
45+
for _ in 0..iterations {
46+
unsafe { memcpy32(dst, src as *const u8, size); }
47+
}
48+
}, 10);
49+
50+
kernel_dur = psp::benchmark(|| {
51+
for _ in 0..iterations {
52+
unsafe { psp::sys::sceKernelMemcpy(dst, src as *const u8, size); }
53+
}
54+
}, 10);
55+
56+
dmac_dur = psp::benchmark(|| {
57+
for _ in 0..iterations {
58+
unsafe { psp::sys::sceDmacMemcpy(dst, src as *const u8, size); }
59+
}
60+
}, 10);
61+
62+
vfpu_dur = psp::benchmark(|| {
63+
for _ in 0..iterations {
64+
unsafe { psp::sys::sceVfpuMemcpy(dst, src as *const u8, size); }
65+
}
66+
}, 10);
67+
68+
unsafe { alloc::alloc::dealloc(src, Layout::from_size_align_unchecked(size, 16)); }
69+
unsafe { alloc::alloc::dealloc(dst, Layout::from_size_align_unchecked(size, 16)); }
70+
71+
let output = format!(
72+
"size: {} bytes
73+
iterations: {}
74+
cpu: {} microseconds
75+
cpu32: {} microseconds
76+
kernel: {} microseconds
77+
dmac: {} microseconds
78+
vfpu: {} microseconds\n\n",
79+
size, iterations, cpu_dur.as_micros(), cpu32_dur.as_micros(),
80+
kernel_dur.as_micros(), dmac_dur.as_micros(),
81+
vfpu_dur.as_micros()
82+
);
83+
write_to_fd(fd, output);
84+
}
85+
unsafe { psp::sys::sceIoClose(fd) };
86+
}
87+
88+
fn write_to_fd(fd: SceUid, msg: alloc::string::String) {
89+
unsafe {
90+
psp::sys::sceIoWrite(
91+
fd,
92+
msg.as_str().as_bytes().as_ptr() as *const u8 as *const c_void,
93+
msg.len()
94+
)
95+
};
6196
}
6297

6398
unsafe fn memcpy(dst: *mut u8, src: *const u8, num: usize) -> *mut u8 {

psp/src/alloc_impl.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,30 +77,39 @@ unsafe extern fn memset(ptr: *mut u8, value: u32, num: usize) -> *mut u8 {
7777
ptr
7878
}
7979

80-
8180
#[no_mangle]
8281
#[cfg(not(feature = "stub-only"))]
83-
unsafe extern fn memcpy(dst: *mut u8, src: *const u8, num: isize) -> *mut u8 {
84-
let mut size = num as usize;
85-
let mut dst32 = dst as *mut u32;
86-
let mut src32 = src as *const u32;
87-
while size > 3 {
88-
*dst32 = *src32;
89-
dst32 = dst32.add(1);
90-
src32 = src32.add(1);
91-
size = size.saturating_sub(4);
92-
}
93-
let mut dst_new = dst32 as *mut u8;
94-
let mut src_new = src32 as *const u8;
95-
while size > 0 {
96-
*dst_new = *src_new;
97-
dst_new = dst_new.add(1);
98-
src_new = src_new.add(1);
99-
size = size.saturating_sub(1);
82+
unsafe extern fn memcpy(dst: *mut u8, src: *const u8, num: usize) -> *mut u8 {
83+
for i in 0..num {
84+
*dst.add(i) = *src.add(i);
10085
}
10186
dst
10287
}
10388

89+
// broke format macro somehow
90+
//#[no_mangle]
91+
//#[cfg(not(feature = "stub-only"))]
92+
//unsafe extern fn memcpy(dst: *mut u8, src: *const u8, num: isize) -> *mut u8 {
93+
//let mut size = num as usize;
94+
//let mut dst32 = dst as *mut u32;
95+
//let mut src32 = src as *const u32;
96+
//while size > 3 {
97+
//*dst32 = *src32;
98+
//dst32 = dst32.add(1);
99+
//src32 = src32.add(1);
100+
//size = size.saturating_sub(4);
101+
//}
102+
//let mut dst_new = dst32 as *mut u8;
103+
//let mut src_new = src32 as *const u8;
104+
//while size > 0 {
105+
//*dst_new = *src_new;
106+
//dst_new = dst_new.add(1);
107+
//src_new = src_new.add(1);
108+
//size = size.saturating_sub(1);
109+
//}
110+
//dst
111+
//}
112+
104113
#[no_mangle]
105114
#[cfg(not(feature = "stub-only"))]
106115
unsafe extern fn memcmp(ptr1: *mut u8, ptr2: *mut u8, num: isize) -> i32 {

psp/src/sys/kernel/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ psp_extern! {
691691
///
692692
/// 1 if interrupts are currently enabled.
693693
pub fn sceKernelIsCpuIntrEnable() -> i32;
694+
695+
#[psp(0x1839852A)]
696+
pub fn sceKernelMemcpy(dst: *mut u8, src: *const u8, num: usize) -> *mut u8;
694697
}
695698

696699
#[repr(C)]

0 commit comments

Comments
 (0)