Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
emscripten_night_7.pdf
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
bokuweb
April 19, 2019
1.6k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
emscripten_night_7.pdf
bokuweb
April 19, 2019
More Decks by bokuweb
See All by bokuweb
1000 行で実現する Linux on Browser
bokuweb
17
9.8k
gocon2019.pdf
bokuweb
5
13k
ファミコンエミュレータの創り方
bokuweb
58
46k
component test
bokuweb
7
5.2k
Featured
See All Featured
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
340
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
850
Deep Space Network (abreviated)
tonyrice
0
320
Speed Design
sergeychernyshev
33
2.1k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
430
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
Typedesign – Prime Four
hannesfritz
42
3.2k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
290
Being A Developer After 40
akosma
91
590k
Become a Pro
speakerdeck
PRO
31
6.3k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
520
Transcript
&NTDSJQUFO8FC"TTFNCMZOJHIU ը૾ॲཧͰൺΔ 8FC"TTFNCMZ !CPLVXFC
!CPLVXFC IUUQCMPHCPLVXFCNF w 8FCϑϩϯτΤϯυΤϯδχΞ w ΈࠐΈϋʔυΣΞΤϯδχΞ w ࢁʹੜଉ CPLVXFC ࣗݾհ
CPLVXFCSVTUZOFT IUUQTHJUIVCDPNCPLVXFCSVTUZOFT
SFHWJ[SFHDMJ
NBQCPYQJYFMNBUDI
XBTNԽͯ͠Έͯ Ͳ͏ͳΔ͔ΈͯΈΔ
QJYFMNBUDIͷಈ͖ Ұக
QJYFMNBUDIͷಈ͖ ෆҰக
QJYFMNBUDIͷಈ͖
for(let y = 0; y < height; y++) { for(let
x = 0; x < width; x++) { if (৭Ұக) { ͘ඳը } else { ബ͘ඳը } } } QJYFMNBUDIͷಈ͖
+4XBTNͷσʔλΓऔΓͲ͏͢Δ͔ ϦχΞϝϞϦ ൪ ೖྗը૾ ೖྗը૾̎ ग़ྗը૾
+BWB4DSJQU
#ZUF NJOJGZޙ +BWB4DSJQU
$
extern "C" uint32_t pixelmatch(const uint8_t *img1, const uint8_t *img2,uint32_t width,ɹuint32_t
height, uint8_t *output){ float maxDelta = 35215 * 0.1 * 0.1; uint32_t diff = 0; for (uint32_t y = 0; y < height; y++) { for (uint32_t x = 0; x < width; x++) { uint32_t pos = (y * width + x) * 4; float delta = colorDelta(img1, img2, pos, pos, false); if (delta > maxDelta) { drawPixel(output, pos, 255, 0, 0); diff++; } else if (output) { uint8_t val = grayPixel(img1, pos, 0.1); drawPixel(output, pos, val, val, val); } } } return diff; } $
emcc -O3 -s ALLOW_MEMORY_GROWTH=1 \ -s EXPORTED_FUNCTIONS=[‘_pixelmatch’] \ -o pixelmatch.js
-s pixelmatch.cpp $
#ZUF ͱάϧʔίʔυͷKT͕,# ࠓճະ༻ 0ͷ߹,# $
3VTU
#[no_mangle] pub extern fn pixelmatch(img1: *mut u8, img2: *mut u8,
width: u32, height: u32, output: *mut u8) -> u32 { let buf1: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(img1, (width * height * 4) as usize) }; let buf2: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(img2, (width * height * 4) as usize) }; let out: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(output, (width * height * 4) as usize) }; let max_delta = 35215.0 * 0.1 * 0.1; let mut diff_count = 0; for y in 0..height { for x in 0..width { let pos = ((y * width + x) * 4) as u32; let delta = color_delta(buf1, buf2, pos, pos, false); if delta > max_delta { draw_pixel(out, pos, 255, 0, 0, 255); diff_count += 1; } else { let y = gray_pixel(buf1, pos, 0.1); draw_pixel(out, pos, y, y, y, 255); } } } diff_count } 3VTU
XBTNQBDLCVJME 3VTU
,#ZUF 3VTU
#![no_std] #[no_mangle] pub extern fn pixelmatch( img1: *mut u8, img2:
*mut u8, width: u32, height: u32, output: *mut u8) -> u32 { … } 3VTU
#ZUF ˣ,#ZUF 3VTU
wasm-opt -O3 -o \ pkg/pixelmatch_optimized.wasm \ pkg/pixelmatch_bg.wasm * macͳΒbrew install
binaryen ͰೖΔ 3VTU
#ZUF ˣ#ZUF 3VTU
wasm-strip pkg/ pixelmatch_optimized.wasm * https://github.com/WebAssembly/wabt ʹؚ·Ε͍ͯΔ 3VTU
#ZUF ˣ#ZUF 3VTU
"TTFNCMZ4DSJQU
export function pixelmatch(img1: u32,img2: u32, width: u32, height: u32): u32
{ let maxDelta = (35215 as f32) * 0.1 * 0.1; let diff = 0; for (let y: u32 = 0; y < height; y++) { for (let x: u32 = 0; x < width; x++) { let pos = (y * width + x) * 4; let delta = colorDelta(img1, img2, pos, pos, false); if (delta > maxDelta) { diff++; drawPixel(img1 + img2, pos, 255, 0, 0); } else { let val = grayPixel(pos, 0.1) as u32; drawPixel(img1 + img2, pos, val, val, val); } } } return diff; } "TTFNCMZ4DSJQU
function get(addr: u32, offset: u32): u8 { return load<u8>(addr +
offset); } function set(addr: u32, offset: u32, value: u8): void { store<u8>(addr + offset, value); } "TTFNCMZ4DSJQU
asc assembly/index.ts -b build/optimized.wasm \ -t build/optimized.wat --validate —optimize \
—importMemory "TTFNCMZ4DSJQU
#ZUF "TTFNCMZ4DSJQU
$ISPNF 4BGBSJ 'JSFGPY 1.6 GHz
Intel Core i5 16 GB 2133 MHz LPDDR3 ops / sec Bigger is better PQTTFD PQTTFD PQTTFD PQTTFD $ 3VTU "4 +4 PQTTFD PQTTFD PQTTFD PQTTFD $ 3VTU "4 +4 PQTTFD PQTTFD PQTTFD PQTTFD $ 3VTU "4 +4 #FODINBSL
(module (type $FUNCSIG$iiiii (func (param i32 i32 i32 i32) (result
i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$fff (func (param f32 f32) (result f32))) (type $FUNCSIG$ffff (func (param f32 f32 f32) (result f32))) (type $FUNCSIG$viiiii (func (param i32 i32 i32 i32 i32))) (type $FUNCSIG$viii (func (param i32 i32 i32))) (type $FUNCSIG$v (func)) (type $FUNCSIG$fiii (func (param i32 i32 i32) (result f32))) (type $FUNCSIG$fi (func (param i32) (result f32))) (import "env" "memory" (memory $0 0)) (table $0 1 funcref) (elem (i32.const 0) $null) (export "memory" (memory $0)) (export "table" (table $0)) (export "pixelmatch" (func $assembly/index/pixelmatch)) (func $assembly/index/get (; 0 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) local.get $0 local.get $1 i32.add i32.load8_u ) "TTFNCMZ4DSJQU
@inline "TTFNCMZ4DSJQU
@inline function get(addr: u32, offset: u32): u8 { return load<u8>(addr
+ offset); } @inline function set(addr: u32, offset: u32, value: u8): void { store<u8>(addr + offset, value); } "TTFNCMZ4DSJQU
#ZUF ˢ#ZUF "TTFNCMZ4DSJQU
$ISPNF 4BGBSJ 'JSFGPY 1.6 GHz
Intel Core i5 16 GB 2133 MHz LPDDR3 ops / sec Bigger is better PQTTFD PQTTFD PQTTFDˢ PQTTFD $ 3VTU "4 +4 PQTTFD PQTTFD PQTTFDˢ PQTTFD $ 3VTU "4 +4 PQTTFD PQTTFD PQTTFDˢ PQTTFD $ 3VTU "4 +4 #FODINBSL ࠶
(module (type (;0;) (func (param i32 i32 i32 i32) (result
f32))) (type (;1;) (func (param i32 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory (;0;) 256)) (func (;0;) (type 0) (param i32 i32 i32 i32) (result f32) (local i32 i32 i32 i32 i32 i32 f32 f32 f32 f32 f32 f32 f32 f32) local.get 0 local.get 2 i32.const 2 i32.add i32.add i32.load8_s local.tee 4 local.get 1 $ DPMPS%FMUB
αΠζ H[JQޙ ops / sec
Smaller is better $ 3VTU "TTFNCMZ4DSJQU +BWB4DSJQU #ZUF #ZUF #ZUF #ZUF
·ͱΊ "ؾʹ͠ͳ͍ͱ+4ΑΓେ͖͘ͳͬͨΓ͘ͳͬͨΓ͢Δ ߹͕͋ΔΑ "ϒϥβʹΑ͔ͬͯͳΓ͘ͳΔʢ͔ʣ͠ ɹϒϥβؒͰͷ͕ࠩࠓճେ͖͘ͳ͔ͬͨΑ
͋Γ͕ͱ͏͍͟͝·ͨ͠ CPLVXFCXBTNQJYFMNBUDI