Allow SIMD vector unit to be toggled on/off #172

Currently defaults to off but future versions may default to on
This commit is contained in:
Lovell Fuller 2015-12-12 09:11:50 +00:00
parent 95cf35efc5
commit 32c4b9eff1
12 changed files with 107 additions and 10 deletions

View File

@ -426,8 +426,6 @@ Use WebP format for the output image.
#### raw()
_Requires libvips 7.42.0+_
Provide raw, uncompressed uint8 (unsigned char) image data for Buffer and Stream based output.
The number of channels depends on the input image and selected options.
@ -497,13 +495,11 @@ An advanced setting for the _zlib_ compression level of the lossless PNG output
#### withoutAdaptiveFiltering()
_Requires libvips 7.42.0+_
An advanced setting to disable adaptive row filtering for the lossless PNG output format.
#### trellisQuantisation() / trellisQuantization()
_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
_Requires libvips to have been compiled with mozjpeg support_
An advanced setting to apply the use of
[trellis quantisation](http://en.wikipedia.org/wiki/Trellis_quantization) with JPEG output.
@ -511,7 +507,7 @@ Reduces file size and slightly increases relative quality at the cost of increas
#### overshootDeringing()
_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
_Requires libvips to have been compiled with mozjpeg support_
An advanced setting to reduce the effects of
[ringing](http://en.wikipedia.org/wiki/Ringing_%28signal%29) in JPEG output,
@ -519,7 +515,7 @@ in particular where black text appears on a white background (or vice versa).
#### optimiseScans() / optimizeScans()
_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
_Requires libvips to have been compiled with mozjpeg support_
An advanced setting for progressive (interlace) JPEG output.
Calculates which spectrum of DCT coefficients uses the fewest bits.
@ -633,3 +629,31 @@ Provides access to internal task counters.
```javascript
var counters = sharp.counters(); // { queue: 2, process: 4 }
```
#### sharp.simd([enable])
_Requires libvips to have been compiled with liborc support_
Improves the performance of `resize`, `blur` and `sharpen` operations
by taking advantage of the SIMD vector unit of the CPU.
* `enable`, if present, is a boolean where `true` enables and `false` disables the use of SIMD.
This method always returns the current state.
This feature is currently disabled by default
but future versions may enable it by default.
When enabled, versions of liborc prior to 0.4.24
and versions of libvips prior to 8.2.0
have been known to crash under heavy load.
```javascript
var simd = sharp.simd();
// simd is `true` is SIMD is currently enabled
```
```javascript
var simd = sharp.simd(true);
// attempts to enable the use of SIMD, returning true if available
```

View File

@ -2,7 +2,12 @@
### v0.12 - "*look*"
#### v0.12.1 - TBD
#### v0.12.1 - 12<sup>th</sup> December 2015
* Allow use of SIMD vector instructions (via liborc) to be toggled on/off.
[#172](https://github.com/lovell/sharp/issues/172)
[@bkw](https://github.com/bkw)
[@puzrin](https://github.com/puzrin)
* Ensure embedded ICC profiles output with perceptual intent.
[#321](https://github.com/lovell/sharp/issues/321)

View File

@ -863,3 +863,15 @@ module.exports.concurrency = function(concurrency) {
module.exports.counters = function() {
return sharp.counters();
};
/*
Get and set use of SIMD vector unit instructions
*/
module.exports.simd = function(simd) {
if (typeof simd !== 'boolean') {
simd = null;
}
return sharp.simd(simd);
};
// Switch off default
module.exports.simd(false);

View File

@ -56,7 +56,7 @@
},
"devDependencies": {
"async": "^1.5.0",
"coveralls": "^2.11.4",
"coveralls": "^2.11.6",
"exif-reader": "^1.0.0",
"icc": "^0.0.2",
"istanbul": "^0.4.0",

2
src/sharp.cc Executable file → Normal file
View File

@ -26,6 +26,8 @@ NAN_MODULE_INIT(init) {
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(concurrency)).ToLocalChecked());
Nan::Set(target, Nan::New("counters").ToLocalChecked(),
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(counters)).ToLocalChecked());
Nan::Set(target, Nan::New("simd").ToLocalChecked(),
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(simd)).ToLocalChecked());
Nan::Set(target, Nan::New("libvipsVersion").ToLocalChecked(),
Nan::GetFunction(Nan::New<v8::FunctionTemplate>(libvipsVersion)).ToLocalChecked());
Nan::Set(target, Nan::New("format").ToLocalChecked(),

View File

@ -1,6 +1,7 @@
#include <cmath>
#include <node.h>
#include <vips/vips.h>
#include <vips/vector.h>
#include "nan.h"
@ -81,6 +82,20 @@ NAN_METHOD(counters) {
info.GetReturnValue().Set(counters);
}
/*
Get and set use of SIMD vector unit instructions
*/
NAN_METHOD(simd) {
HandleScope();
// Set state
if (info[0]->IsBoolean()) {
vips_vector_set_enabled(To<bool>(info[0]).FromJust());
}
// Get state
info.GetReturnValue().Set(New<Boolean>(vips_vector_isenabled()));
}
/*
Get libvips version
*/

1
src/utilities.h Executable file → Normal file
View File

@ -6,6 +6,7 @@
NAN_METHOD(cache);
NAN_METHOD(concurrency);
NAN_METHOD(counters);
NAN_METHOD(simd);
NAN_METHOD(libvipsVersion);
NAN_METHOD(format);
NAN_METHOD(_maxColourDistance);

View File

@ -13,7 +13,7 @@
"gm": "^1.21.0",
"imagemagick": "^0.1.3",
"imagemagick-native": "elad/node-imagemagick-native",
"jimp": "^0.2.19",
"jimp": "^0.2.20",
"lwip": "^0.0.8",
"semver": "^5.1.0"
},

View File

@ -12,6 +12,7 @@ var width = 720;
var height = 480;
sharp.concurrency(1);
sharp.simd(true);
var timer = setInterval(function() {
console.dir(sharp.counters());

View File

@ -35,6 +35,8 @@ var magickFilterBicubic = 'Lanczos';
// Disable libvips cache to ensure tests are as fair as they can be
sharp.cache(0);
// Enable use of SIMD
sharp.simd(true);
async.series({
'jpeg-linear': function(callback) {
@ -496,6 +498,24 @@ async.series({
}
});
}
}).add('sharp-without-simd', {
defer: true,
fn: function(deferred) {
sharp.simd(false);
sharp(inputJpgBuffer)
.rotate(90)
.interpolateWith(sharp.interpolator.bilinear)
.resize(width, height)
.toBuffer(function(err, buffer) {
sharp.simd(true);
if (err) {
throw err;
} else {
assert.notStrictEqual(null, buffer);
deferred.resolve();
}
});
}
}).add('sharp-sequentialRead', {
defer: true,
fn: function(deferred) {

View File

@ -8,6 +8,8 @@ var Benchmark = require('benchmark');
var sharp = require('../../index');
var fixtures = require('../fixtures');
sharp.simd(true);
var min = 320;
var max = 960;

View File

@ -51,6 +51,21 @@ describe('Utilities', function() {
});
});
describe('SIMD', function() {
it('Can get current state', function() {
var simd = sharp.simd();
assert.strictEqual(typeof simd, 'boolean');
});
it('Can disable', function() {
var simd = sharp.simd(false);
assert.strictEqual(simd, false);
});
it('Can attempt to enable', function() {
var simd = sharp.simd(true);
assert.strictEqual(typeof simd, 'boolean');
});
});
describe('Format', function() {
it('Contains expected attributes', function() {
assert.strictEqual('object', typeof sharp.format);