2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#![feature(test)]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#![cfg(feature = "bpf_c")]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								extern crate test;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-26 07:49:23 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-23 11:03:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use solana_rbpf::EbpfVm;
							 | 
						
					
						
							
								
									
										
										
										
											2020-01-28 17:03:37 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								use std::{env, fs::File, io::Error, io::Read, mem, path::PathBuf};
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								use test::Bencher;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/// BPF program file extension
							 | 
						
					
						
							
								
									
										
										
										
											2018-12-04 22:03:32 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								const PLATFORM_FILE_EXTENSION_BPF: &str = "so";
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/// Create a BPF program file name
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn create_bpf_path(name: &str) -> PathBuf {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut pathbuf = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        let current_exe = env::current_exe().unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        PathBuf::from(current_exe.parent().unwrap().parent().unwrap())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pathbuf.push("bpf/");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pathbuf.push(name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pathbuf.set_extension(PLATFORM_FILE_EXTENSION_BPF);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    pathbuf
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn empty_check(_prog: &[u8]) -> Result<(), Error> {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Ok(())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-04 09:56:27 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								fn load_elf() -> Result<Vec<u8>, std::io::Error> {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let path = create_bpf_path("bench_alu");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut file = File::open(&path).expect(&format!("Unable to open {:?}", path));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut elf = Vec::new();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    file.read_to_end(&mut elf).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Ok(elf)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const ARMSTRONG_LIMIT: u64 = 500;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								const ARMSTRONG_EXPECTED: u64 = 5;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[bench]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn bench_program_load_elf(bencher: &mut Bencher) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-04 09:56:27 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let elf = load_elf().unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-23 11:03:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let mut vm = EbpfVm::new(None).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    vm.set_verifier(empty_check).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bencher.iter(|| {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        vm.set_elf(&elf).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[bench]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn bench_program_verify(bencher: &mut Bencher) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-04 09:56:27 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let elf = load_elf().unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-23 11:03:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let mut vm = EbpfVm::new(None).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    vm.set_verifier(empty_check).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    vm.set_elf(&elf).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bencher.iter(|| {
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-20 16:32:19 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        vm.set_verifier(solana_bpf_loader_program::bpf_verifier::check)
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            .unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#[bench]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								fn bench_program_alu(bencher: &mut Bencher) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let ns_per_s = 1000000000;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let one_million = 1000000;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mut inner_iter = vec![];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    inner_iter
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .write_u64::<LittleEndian>(ARMSTRONG_LIMIT)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        .unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-26 07:49:23 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    inner_iter.write_u64::<LittleEndian>(0).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-04 09:56:27 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let elf = load_elf().unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-20 16:32:19 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    let (mut vm, _) = solana_bpf_loader_program::create_vm(&elf).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    println!("Interpreted:");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    assert_eq!(
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-06 16:05:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        0, /*success*/
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-24 16:21:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        vm.execute_program(&mut inner_iter, &[], &[]).unwrap()
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    );
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-26 07:49:23 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    assert_eq!(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ARMSTRONG_EXPECTED,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    bencher.iter(|| {
							 | 
						
					
						
							
								
									
										
										
										
											2019-05-24 16:21:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        vm.execute_program(&mut inner_iter, &[], &[]).unwrap();
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let instructions = vm.get_last_instruction_count();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let summary = bencher.bench(|_bencher| {}).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    println!("  {:?} instructions", instructions);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    println!("  {:?} ns/iter median", summary.median as u64);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    assert!(0f64 != summary.median);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    println!("  {:?} MIPS", mips);
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-21 12:16:16 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_interpreted_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-23 11:03:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // JIT disabled until address translation support is added
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // println!("JIT to native:");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // vm.jit_compile().unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // unsafe {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //     assert_eq!(
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-06 16:05:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    //         0, /*success*/
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-23 11:03:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    //         vm.execute_program_jit(&mut inner_iter).unwrap()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //     );
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // assert_eq!(ARMSTRONG_LIMIT, LittleEndian::read_u64(&inner_iter));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // assert_eq!(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //     ARMSTRONG_EXPECTED,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //     LittleEndian::read_u64(&inner_iter[mem::size_of::<u64>()..])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // );
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-26 07:49:23 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-23 11:03:53 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    // bencher.iter(|| unsafe {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    //     vm.execute_program_jit(&mut inner_iter).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // });
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // let summary = bencher.bench(|_bencher| {}).unwrap();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // println!("  {:?} instructions", instructions);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // println!("  {:?} ns/iter median", summary.median as u64);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // assert!(0f64 != summary.median);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // let mips = (instructions * (ns_per_s / summary.median as u64)) / one_million;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // println!("  {:?} MIPS", mips);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    // println!("{{ \"type\": \"bench\", \"name\": \"bench_program_alu_jit_to_native_mips\", \"median\": {:?}, \"deviation\": 0 }}", mips);
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-14 12:06:06 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |