Skip to content

Commit

Permalink
Add option for changing number of threads at runtime
Browse files Browse the repository at this point in the history
Closes #39
  • Loading branch information
Joshua Holmer committed May 4, 2016
1 parent e4cd9b8 commit 3a39b13
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 143 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- Minor compression improvement on interlaced images
- Performance optimizations
- [SEMVER_MINOR] Move default Options into a Default impl
- [SEMVER_MINOR] Add option for setting number of threads ([#39](https://github.com/shssoichiro/oxipng/issues/39))

**Version 0.6.0**
- Fix issue where output directory would not be created if it did not exist
Expand Down
11 changes: 8 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub struct Options {
/// Whether to use heuristics to pick the best filter and compression
/// Intended for use with `-o 1` from the CLI interface
pub use_heuristics: bool,
/// Number of threads to use, defaults to 1.5x CPU cores, rounded down
pub threads: usize,
}

impl Default for Options {
Expand All @@ -96,6 +98,10 @@ impl Default for Options {
strategies.insert(i);
}

// Default to 1 thread on single-core, otherwise use threads = 1.5x CPU cores
let num_cpus = num_cpus::get();
let thread_count = num_cpus + (num_cpus >> 1);

Options {
backup: false,
out_file: PathBuf::new(),
Expand All @@ -121,6 +127,7 @@ impl Default for Options {
idat_recoding: true,
strip: png::Headers::None,
use_heuristics: false,
threads: thread_count,
}
}
}
Expand Down Expand Up @@ -200,9 +207,7 @@ pub fn optimize(filepath: &Path, opts: &Options) -> Result<(), String> {
let something_changed = perform_reductions(&mut png, &opts);

if opts.idat_recoding || something_changed {
// Use 1 thread on single-core, otherwise use threads = 1.5x CPU cores
let num_cpus = num_cpus::get();
let thread_count = num_cpus + (num_cpus >> 1);
let thread_count = opts.threads;
let pool = Pool::new(thread_count);
// Go through selected permutations and determine the best
let best: Arc<Mutex<Option<TrialWithData>>> = Arc::new(Mutex::new(None));
Expand Down
21 changes: 21 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,23 @@ fn main() {
.help("Strip safely-removable metadata objects")
.short("s")
.conflicts_with("strip"))
.arg(Arg::with_name("threads")
.help("Set number of threads to use - default 1.5x CPU cores")
.long("threads")
.short("t")
.takes_value(true)
.validator(|x| {
match x.parse::<usize>() {
Ok(val) => {
if val > 0 {
Ok(())
} else {
Err("Thread count must be >= 1".to_owned())
}
}
Err(_) => Err("Thread count must be >= 1".to_owned()),
}
}))
.after_help("Optimization levels:
-o 0 => --zc 3 --nz (0 or 1 trials)
-o 1 => --zc 9 (1 trial, determined heuristically)
Expand Down Expand Up @@ -478,6 +495,10 @@ fn parse_opts_into_struct(matches: &ArgMatches, opts: &mut oxipng::Options) -> R
opts.strip = png::Headers::Safe;
}

if let Some(x) = matches.value_of("threads") {
opts.threads = x.parse::<usize>().unwrap();
}

Ok(())
}

Expand Down
42 changes: 7 additions & 35 deletions tests/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,15 @@ use std::path::Path;
use std::path::PathBuf;

fn get_opts(input: &Path) -> oxipng::Options {
let mut options = oxipng::Options::default();
options.out_file = input.with_extension("out.png").to_owned();
options.verbosity = None;
options.force = true;
let mut filter = HashSet::new();
filter.insert(0);
let mut compression = HashSet::new();
compression.insert(9);
let mut memory = HashSet::new();
memory.insert(9);
let mut strategies = HashSet::new();
for i in 0..4 {
strategies.insert(i);
}

oxipng::Options {
backup: false,
out_file: input.with_extension("out.png").to_owned(),
out_dir: None,
stdout: false,
pretend: false,
recursive: false,
fix_errors: false,
force: true,
clobber: true,
create: true,
preserve_attrs: false,
verbosity: None,
filter: filter,
interlace: None,
compression: compression,
memory: memory,
strategies: strategies,
window: 15,
bit_depth_reduction: true,
color_type_reduction: true,
palette_reduction: true,
idat_recoding: true,
strip: png::Headers::None,
use_heuristics: false,
}
options.filter = filter;

options
}

fn test_it_converts(input: &Path,
Expand Down
42 changes: 7 additions & 35 deletions tests/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,15 @@ use std::path::Path;
use std::path::PathBuf;

fn get_opts(input: &Path) -> oxipng::Options {
let mut options = oxipng::Options::default();
options.out_file = input.with_extension("out.png").to_owned();
options.verbosity = None;
options.force = true;
let mut filter = HashSet::new();
filter.insert(0);
let mut compression = HashSet::new();
compression.insert(9);
let mut memory = HashSet::new();
memory.insert(9);
let mut strategies = HashSet::new();
for i in 0..4 {
strategies.insert(i);
}

oxipng::Options {
backup: false,
out_file: input.with_extension("out.png").to_owned(),
out_dir: None,
stdout: false,
pretend: false,
recursive: false,
fix_errors: false,
force: true,
clobber: true,
create: true,
preserve_attrs: false,
verbosity: None,
filter: filter,
interlace: None,
compression: compression,
memory: memory,
strategies: strategies,
window: 15,
bit_depth_reduction: true,
color_type_reduction: true,
palette_reduction: true,
idat_recoding: true,
strip: png::Headers::None,
use_heuristics: false,
}
options.filter = filter;

options
}

fn test_it_converts(input: &Path,
Expand Down
42 changes: 7 additions & 35 deletions tests/interlaced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,15 @@ use std::path::Path;
use std::path::PathBuf;

fn get_opts(input: &Path) -> oxipng::Options {
let mut options = oxipng::Options::default();
options.out_file = input.with_extension("out.png").to_owned();
options.verbosity = None;
options.force = true;
let mut filter = HashSet::new();
filter.insert(0);
let mut compression = HashSet::new();
compression.insert(9);
let mut memory = HashSet::new();
memory.insert(9);
let mut strategies = HashSet::new();
for i in 0..4 {
strategies.insert(i);
}

oxipng::Options {
backup: false,
out_file: input.with_extension("out.png").to_owned(),
out_dir: None,
stdout: false,
pretend: false,
recursive: false,
fix_errors: false,
force: true,
clobber: true,
create: true,
preserve_attrs: false,
verbosity: None,
filter: filter,
interlace: None,
compression: compression,
memory: memory,
strategies: strategies,
window: 15,
bit_depth_reduction: true,
color_type_reduction: true,
palette_reduction: true,
idat_recoding: true,
strip: png::Headers::None,
use_heuristics: false,
}
options.filter = filter;

options
}

fn test_it_converts(input: &Path,
Expand Down
42 changes: 7 additions & 35 deletions tests/reduction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,15 @@ use std::path::Path;
use std::path::PathBuf;

fn get_opts(input: &Path) -> oxipng::Options {
let mut options = oxipng::Options::default();
options.out_file = input.with_extension("out.png").to_owned();
options.verbosity = None;
options.force = true;
let mut filter = HashSet::new();
filter.insert(0);
let mut compression = HashSet::new();
compression.insert(9);
let mut memory = HashSet::new();
memory.insert(9);
let mut strategies = HashSet::new();
for i in 0..4 {
strategies.insert(i);
}

oxipng::Options {
backup: false,
out_file: input.with_extension("out.png").to_owned(),
out_dir: None,
stdout: false,
pretend: false,
recursive: false,
fix_errors: false,
force: true,
clobber: true,
create: true,
preserve_attrs: false,
verbosity: None,
filter: filter,
interlace: None,
compression: compression,
memory: memory,
strategies: strategies,
window: 15,
bit_depth_reduction: true,
color_type_reduction: true,
palette_reduction: true,
idat_recoding: true,
strip: png::Headers::None,
use_heuristics: false,
}
options.filter = filter;

options
}

fn test_it_converts(input: &Path,
Expand Down

0 comments on commit 3a39b13

Please sign in to comment.