SlideShare une entreprise Scribd logo
1  sur  72
Télécharger pour lire hors ligne
try! Swift Tokyo 2018
Shuichi Tsutsumi
@shu223
UIImageView vs Metal
Shuichi Tsutsumi @shu223
• iOS Developer
- @Fyusion Inc.
- @Freelance
Today’s Goal
• Learn “how to use Metal”
• Be conscious the GPU layer through Metal
Agenda
• Compare the graphics rendering performance of
Metal to UIImageView
→ Learn a lot around GPU
1. UIKit is optimized well with GPU.
2. Consider also the GPU, when measuring the performance.
3. Pay attention to the processing flow between CPU and GPU.
4. Be careful where the resource is.
imageView.image = image
What’s happening?
ScreenProcessor
Frame
Buffer
Pixel Data for a frame
Write 60 times/sec
Draw Pixels
* Resolution
Difference Between CPU and GPU
CPU is a Sports Car
• Very fast
• Can’t process many tasks in
parallel
GPU is a Bus
• Not as fast as CPU
• Can process many “same” tasks
in parallel
• CPU is very fast, good for any tasks (general-purpose
processor)
- However, if used to process everything, it will easily reach to
100% load.
→ Utilize GPU as much as possible, 

if the task is good for GPU

(= can be computed in parallel)
Processor ScreenFrame
Buffer
Write 60 times/sec
* Resolution
Pixel Data for 1 frame
GPU
What’s ?
Provide access to GPU
GPU
Your app
???
What’s the difference from
OpenGL?
OpenGL
• Cross-platform
• Supports many vendors’ GPUs
Metal
• Developed by Apple
• Optimized for Apple’s hardware
• 10x faster than OpenGL
Sounds great!
Metal Implementation
imageView.image = image
To achieve this with Metal…
func draw(in view: MTKView) {
guard let drawable = view.currentDrawable else {return}
guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalError()}
guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fatalError()}
let w = min(texture.width, drawable.texture.width)
let h = min(texture.height, drawable.texture.height)
blitEncoder.copy(from: texture,
sourceSlice: 0,
sourceLevel: 0,
sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0),
sourceSize: MTLSizeMake(w, h, texture.depth),
to: drawable.texture,
destinationSlice: 0,
destinationLevel: 0,
destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0))
blitEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
}
private let device = MTLCreateSystemDefaultDevice()!


private func setup() {
commandQueue = device.makeCommandQueue()
let textureLoader = MTKTextureLoader(device: device)
texture = try! textureLoader.newTexture(
name: "highsierra",
scaleFactor: view.contentScaleFactor,
bundle: nil)
mtkView.device = device
mtkView.delegate = self
mtkView.colorPixelFormat = texture.pixelFormat
}
this is the Minimumimplementation
private let device = MTLCreateSystemDefaultDevice()!


private func setup() {
commandQueue = device.makeCommandQueue()
let textureLoader = MTKTextureLoader(device: device)
texture = try! textureLoader.newTexture(
name: "highsierra",
scaleFactor: view.contentScaleFactor,
bundle: nil)
mtkView.device = device
mtkView.delegate = self
mtkView.colorPixelFormat = texture.pixelFormat
}
func draw(in view: MTKView) {
guard let drawable = view.currentDrawable else {return}
guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalE
guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fa
let w = min(texture.width, drawable.texture.width)
let h = min(texture.height, drawable.texture.height)
blitEncoder.copy(from: texture,
sourceSlice: 0,
sourceLevel: 0,
sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0),
sourceSize: MTLSizeMake(w, h, texture.depth),
to: drawable.texture,
destinationSlice: 0,
destinationLevel: 0,
destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0))
blitEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
}
imageView.image = image
private let device = MTLCreateSystemDefaultDevice()!


private func setup() {
commandQueue = device.makeCommandQueue()
let textureLoader = MTKTextureLoader(device: device)
texture = try! textureLoader.newTexture(
name: "highsierra",
scaleFactor: view.contentScaleFactor,
bundle: nil)
mtkView.device = device
mtkView.delegate = self
mtkView.colorPixelFormat = texture.pixelFormat
}
func draw(in view: MTKView) {
guard let drawable = view.currentDrawable else {return}
guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalE
guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fa
let w = min(texture.width, drawable.texture.width)
let h = min(texture.height, drawable.texture.height)
blitEncoder.copy(from: texture,
sourceSlice: 0,
sourceLevel: 0,
sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0),
sourceSize: MTLSizeMake(w, h, texture.depth),
to: drawable.texture,
destinationSlice: 0,
destinationLevel: 0,
destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0))
blitEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
commandBuffer.waitUntilCompleted()
}
imageView.image = image
💡
My Idea:
A Metal wrapper class to draw an image
✓ Easy to use as UIImageView
✓ Metal Accelerated
“MetalImageView”
metalImageView.texture = texture
Powered by
Performance comparison
with UIImageView
Sample App
for the comparison
• Render large images in table cells.
- 5120 x 3200 (elcapitan.jpg)
- 1245 x 1245 (sierra.png)
Measuring Code
let time1 = CACurrentMediaTime()
if isMetal {
let metalCell = cell as! MetalTableViewCell
metalCell.metalImageView.textureName = name
} else {
let uikitCell = cell as! TableViewCell
uikitCell.uiImageView.image = UIImage(named: name)
}
let time2 = CACurrentMediaTime()
print("time:(time2-time1)")
Time
Interval
Render with UIImageView
Render with Metal
Results
• Metal is 10x - 20x faster!
Time to render an image
UIImageView 0.4 - 0.6 msec
Metal 0.02 - 0.05 msec
iPhone 6s
Something weird
Metal is more lagging, choppy
UIImageView Metal
Measuring Code
let time1 = CACurrentMediaTime()
if isMetal {
let metalCell = cell as! MetalTableViewCell
metalCell.metalImageView.textureName = name
} else {
let uikitCell = cell as! TableViewCell
uikitCell.uiImageView.image = UIImage(named: name)
}
let time2 = CACurrentMediaTime()
print("time:(time2-time1)")
Basic Concept
2. CPU creates GPU commands 

as a command buffer
1. Load image data to memory 

for GPU (& CPU)
4. GPU processes
the commands
3. Push it to GPU
let time1 = CACurrentMediaTime()
if isMetal {
let metalCell = cell as! MetalTableViewCell
metalCell.metalImageView.textureName = name
} else {
let uikitCell = cell as! TableViewCell
uikitCell.uiImageView.image = UIImage(named: name)
}
let time2 = CACurrentMediaTime()
print("time:(time2-time1)")
2. CPU creates GPU commands 

as a command buffer
1. Load image data to memory 

for GPU (& CPU)
3. Push it to GPU
4. GPU processes
the commands
NOT Considered!
• Measure the time until the GPU processing is completed
func draw(in view: MTKView) {
// Prepare the command buffer
...
// Push the command buffer
commandBuffer.commit()
// Wait
commandBuffer.waitUntilCompleted()
// Measure
let endTime = CACurrentMediaTime()
print(“Time: (endTime - startTime)”)
}
Fixed measuring code
Submit commands to GPU
Wait until the GPU processing
is completed
Calculate the total time
Results
• Metal is SLOWER !?
- Less than 30fps even the best case
→ My implementation should have problems
• UIImageView is fast enough anyways.
Time to render an image
UIImageView 0.4 - 0.6 msec
Metal 40 - 200 msec
Why does UIImageView so fast?
※WWDC17 Platforms State of the Unionより
UIKit internally uses Metal
• UIKit has been updated, and optimized well.
• Should use UIKit rather than making a custom UI
component with low level APIs (e.g. Metal) unless
there is particular reasons it can be better.
Point 1:
UIKit is optimized well
with GPU
Point 2:
Consider also the GPU, 

when measuring the performance
Why was MetalImageView so slow?
What was the problem?
(My Metal Wrapper)
Profile using Instruments
Metal System Trace
On CPU
On GPU
Create command buffers etc.(on CPU)
Submit command buffers etc.(on CPU)
Process shaders(on GPU)
On CPU
On GPU
Problem 1
Resize
(MPSImageLanczosScale)
Render
(MTLBlitCommandEncoder)
Unexpected interval
Measuring Time
Current processing flow
1. Resize with MPSImageLanczosScale
2. After 1 is completed, call setNeedsDisplay()
3. draw(in:) of MTKViewDelegate is called
4. Render to screen in the draw(in:)
Problem
The CPU is waiting for the GPU
On CPU
On GPU
Resize
Render
2. CPU creates GPU commands 

as a command buffer
4. GPU processes
the commands
3. Push it to
GPU
FIX: Combined the commands
• Encode both commands into a command buffer
- Resize
- Render
• Push the command buffer to a GPU
2. CPU creates GPU commands 

as a command buffer
4. GPU processes
the commands
3. Push it to
GPU
Resize
Render
Resize Render
Unexpected interval
Combine
Resize Render Resize+Render
Point 3:
Pay attention to the processing flow
between CPU and GPU
Problem 2
Speculation:
Loading textures is the bottleneck(?)
1. Load image data to
memory 

for GPU (& CPU)
Measure the time to load textures
let startTime = CACurrentMediaTime()
textureLoader.newTexture(name: name, scaleFactor: scaleFactor, bundle: nil) { (texture,
error) in
let endTime = CACurrentMediaTime()
print("Time to load (name): (endTime - startTime)")
• Results: 20 - 500 msec
→ It’s the bottleneck!
Fix: Cache the loaded textures
• UIImage(named:) caches internally, too
• “Caching loaded image data” is NOT a Metal/GPU
specific idea.
Metal/GPU specific point:
“Where is the resource?”
Memory for GPU
(& CPU)
private var cachedTextures: [String: MTLTexture] = [:]OK
private var cachedImages: [String: UIImage] = [:]NG
After adopting Cache
Point 4:
Be careful where the resource is.
Wrap up
Today’s Goal
• Learn “how to use Metal”
• Be conscious the GPU layer through Metal
• Compared the graphics rendering performance of
Metal to UIImageView
→ Learned a lot around GPU
1. UIKit is optimized well with GPU.
2. Consider also the GPU, when measuring the performance.
3. Pay attention to the processing flow between CPU and GPU.
4. Be careful where the resource is.
Thank you!
https://github.com/shu223

Contenu connexe

Similaire à UIImageView vs Metal #tryswiftconf

Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)
Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)
Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)Johan Andersson
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotXamarin
 
Tales from the Optimization Trenches - Unite Copenhagen 2019
Tales from the Optimization Trenches - Unite Copenhagen 2019Tales from the Optimization Trenches - Unite Copenhagen 2019
Tales from the Optimization Trenches - Unite Copenhagen 2019Unity Technologies
 
GPU-Accelerated Parallel Computing
GPU-Accelerated Parallel ComputingGPU-Accelerated Parallel Computing
GPU-Accelerated Parallel ComputingJun Young Park
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
2013-05-15 threads. why and how
2013-05-15 threads. why and how2013-05-15 threads. why and how
2013-05-15 threads. why and howCocoaHeads Tricity
 
Writing 3D Applications Using ruby-processing
Writing 3D Applications Using ruby-processingWriting 3D Applications Using ruby-processing
Writing 3D Applications Using ruby-processingPreston Lee
 
Intro to GPGPU Programming with Cuda
Intro to GPGPU Programming with CudaIntro to GPGPU Programming with Cuda
Intro to GPGPU Programming with CudaRob Gillen
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Alessandro Molina
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computingArka Ghosh
 
SMP implementation for OpenBSD/sgi
SMP implementation for OpenBSD/sgiSMP implementation for OpenBSD/sgi
SMP implementation for OpenBSD/sgiTakuya ASADA
 
SPU gameplay
SPU gameplaySPU gameplay
SPU gameplaySlide_N
 
SproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFestSproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFesttomdale
 
Naive application development
Naive application developmentNaive application development
Naive application developmentShaka Huang
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computingArka Ghosh
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computingArka Ghosh
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computingArka Ghosh
 

Similaire à UIImageView vs Metal #tryswiftconf (20)

Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)
Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)
Parallel Graphics in Frostbite - Current & Future (Siggraph 2009)
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien Pouliot
 
Tales from the Optimization Trenches - Unite Copenhagen 2019
Tales from the Optimization Trenches - Unite Copenhagen 2019Tales from the Optimization Trenches - Unite Copenhagen 2019
Tales from the Optimization Trenches - Unite Copenhagen 2019
 
20131212
2013121220131212
20131212
 
GPU-Accelerated Parallel Computing
GPU-Accelerated Parallel ComputingGPU-Accelerated Parallel Computing
GPU-Accelerated Parallel Computing
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
2013-05-15 threads. why and how
2013-05-15 threads. why and how2013-05-15 threads. why and how
2013-05-15 threads. why and how
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Writing 3D Applications Using ruby-processing
Writing 3D Applications Using ruby-processingWriting 3D Applications Using ruby-processing
Writing 3D Applications Using ruby-processing
 
Intro to GPGPU Programming with Cuda
Intro to GPGPU Programming with CudaIntro to GPGPU Programming with Cuda
Intro to GPGPU Programming with Cuda
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computing
 
SMP implementation for OpenBSD/sgi
SMP implementation for OpenBSD/sgiSMP implementation for OpenBSD/sgi
SMP implementation for OpenBSD/sgi
 
SPU gameplay
SPU gameplaySPU gameplay
SPU gameplay
 
SproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFestSproutCore is Awesome - HTML5 Summer DevFest
SproutCore is Awesome - HTML5 Summer DevFest
 
Cocos2d 소개 - Korea Linux Forum 2014
Cocos2d 소개 - Korea Linux Forum 2014Cocos2d 소개 - Korea Linux Forum 2014
Cocos2d 소개 - Korea Linux Forum 2014
 
Naive application development
Naive application developmentNaive application development
Naive application development
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computing
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computing
 
Vpu technology &gpgpu computing
Vpu technology &gpgpu computingVpu technology &gpgpu computing
Vpu technology &gpgpu computing
 

Plus de Shuichi Tsutsumi

Core MLのアップデートを3倍楽しむ方法 #wwdctokyo
Core MLのアップデートを3倍楽しむ方法 #wwdctokyoCore MLのアップデートを3倍楽しむ方法 #wwdctokyo
Core MLのアップデートを3倍楽しむ方法 #wwdctokyoShuichi Tsutsumi
 
エンジニアという仕事を楽しみ続けるためのキャリア戦略
エンジニアという仕事を楽しみ続けるためのキャリア戦略エンジニアという仕事を楽しみ続けるためのキャリア戦略
エンジニアという仕事を楽しみ続けるためのキャリア戦略Shuichi Tsutsumi
 
Deep Learning on iOS #360iDev
Deep Learning on iOS #360iDevDeep Learning on iOS #360iDev
Deep Learning on iOS #360iDevShuichi Tsutsumi
 
Building iOS apps using "Bluetooth Low Energy"
Building iOS apps using "Bluetooth Low Energy"Building iOS apps using "Bluetooth Low Energy"
Building iOS apps using "Bluetooth Low Energy"Shuichi Tsutsumi
 
Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016
Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016
Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016Shuichi Tsutsumi
 
Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016
Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016
Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016Shuichi Tsutsumi
 
オープンソースエコシステム #demodaytokyo
オープンソースエコシステム #demodaytokyoオープンソースエコシステム #demodaytokyo
オープンソースエコシステム #demodaytokyoShuichi Tsutsumi
 
Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9Shuichi Tsutsumi
 
Core Graphics on watchOS 2
Core Graphics on watchOS 2Core Graphics on watchOS 2
Core Graphics on watchOS 2Shuichi Tsutsumi
 
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Shuichi Tsutsumi
 
iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編Shuichi Tsutsumi
 
UI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つUI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つShuichi Tsutsumi
 
watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話Shuichi Tsutsumi
 
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜Shuichi Tsutsumi
 
WatchKitを実際にさわってみてわかったこと
WatchKitを実際にさわってみてわかったことWatchKitを実際にさわってみてわかったこと
WatchKitを実際にさわってみてわかったことShuichi Tsutsumi
 
おもしろく働くための「わらしべ長者方式」
おもしろく働くための「わらしべ長者方式」おもしろく働くための「わらしべ長者方式」
おもしろく働くための「わらしべ長者方式」Shuichi Tsutsumi
 

Plus de Shuichi Tsutsumi (20)

Core MLのアップデートを3倍楽しむ方法 #wwdctokyo
Core MLのアップデートを3倍楽しむ方法 #wwdctokyoCore MLのアップデートを3倍楽しむ方法 #wwdctokyo
Core MLのアップデートを3倍楽しむ方法 #wwdctokyo
 
エンジニアという仕事を楽しみ続けるためのキャリア戦略
エンジニアという仕事を楽しみ続けるためのキャリア戦略エンジニアという仕事を楽しみ続けるためのキャリア戦略
エンジニアという仕事を楽しみ続けるためのキャリア戦略
 
Depth in Depth #iOSDC
Depth in Depth #iOSDCDepth in Depth #iOSDC
Depth in Depth #iOSDC
 
Deep Learning on iOS #360iDev
Deep Learning on iOS #360iDevDeep Learning on iOS #360iDev
Deep Learning on iOS #360iDev
 
Client-Side Deep Learning
Client-Side Deep LearningClient-Side Deep Learning
Client-Side Deep Learning
 
Building iOS apps using "Bluetooth Low Energy"
Building iOS apps using "Bluetooth Low Energy"Building iOS apps using "Bluetooth Low Energy"
Building iOS apps using "Bluetooth Low Energy"
 
Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016
Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016
Practical Core Bluetooth in IoT & Wearable projects @ AltConf 2016
 
Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016
Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016
Practical Core Bluetooth in IoT & Wearable projects @ UIKonf 2016
 
オープンソースエコシステム #demodaytokyo
オープンソースエコシステム #demodaytokyoオープンソースエコシステム #demodaytokyo
オープンソースエコシステム #demodaytokyo
 
Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9Core Image Tips & Tricks in iOS 9
Core Image Tips & Tricks in iOS 9
 
Core Graphics on watchOS 2
Core Graphics on watchOS 2Core Graphics on watchOS 2
Core Graphics on watchOS 2
 
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
Audio Unit Extensions 〜オーディオエフェクトのアプリ間共有〜
 
iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編iOS 9 の新機能 Core Image 編
iOS 9 の新機能 Core Image 編
 
UI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つUI/UX に影響の大きい watchOS 2 の新機能 3つ
UI/UX に影響の大きい watchOS 2 の新機能 3つ
 
watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話watchOS 2 新機能の細かい話
watchOS 2 新機能の細かい話
 
Apple Watch 間通信
Apple Watch 間通信Apple Watch 間通信
Apple Watch 間通信
 
OpenCV 3.0 on iOS
OpenCV 3.0 on iOSOpenCV 3.0 on iOS
OpenCV 3.0 on iOS
 
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
殺しても死なないアプリ 〜Core Bluetooth の「状態の保存と復元」機能〜
 
WatchKitを実際にさわってみてわかったこと
WatchKitを実際にさわってみてわかったことWatchKitを実際にさわってみてわかったこと
WatchKitを実際にさわってみてわかったこと
 
おもしろく働くための「わらしべ長者方式」
おもしろく働くための「わらしべ長者方式」おもしろく働くための「わらしべ長者方式」
おもしろく働くための「わらしべ長者方式」
 

Dernier

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 

Dernier (20)

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 

UIImageView vs Metal #tryswiftconf

  • 1. try! Swift Tokyo 2018 Shuichi Tsutsumi @shu223 UIImageView vs Metal
  • 2. Shuichi Tsutsumi @shu223 • iOS Developer - @Fyusion Inc. - @Freelance
  • 3. Today’s Goal • Learn “how to use Metal” • Be conscious the GPU layer through Metal
  • 4. Agenda • Compare the graphics rendering performance of Metal to UIImageView → Learn a lot around GPU 1. UIKit is optimized well with GPU. 2. Consider also the GPU, when measuring the performance. 3. Pay attention to the processing flow between CPU and GPU. 4. Be careful where the resource is.
  • 6.
  • 8. ScreenProcessor Frame Buffer Pixel Data for a frame Write 60 times/sec Draw Pixels * Resolution
  • 9. Difference Between CPU and GPU CPU is a Sports Car • Very fast • Can’t process many tasks in parallel GPU is a Bus • Not as fast as CPU • Can process many “same” tasks in parallel
  • 10. • CPU is very fast, good for any tasks (general-purpose processor) - However, if used to process everything, it will easily reach to 100% load. → Utilize GPU as much as possible, 
 if the task is good for GPU
 (= can be computed in parallel)
  • 11. Processor ScreenFrame Buffer Write 60 times/sec * Resolution Pixel Data for 1 frame GPU
  • 13. Provide access to GPU GPU Your app ???
  • 14. What’s the difference from OpenGL?
  • 16. Metal • Developed by Apple • Optimized for Apple’s hardware • 10x faster than OpenGL
  • 20.
  • 21. To achieve this with Metal…
  • 22. func draw(in view: MTKView) { guard let drawable = view.currentDrawable else {return} guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalError()} guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fatalError()} let w = min(texture.width, drawable.texture.width) let h = min(texture.height, drawable.texture.height) blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSizeMake(w, h, texture.depth), to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0)) blitEncoder.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() commandBuffer.waitUntilCompleted() } private let device = MTLCreateSystemDefaultDevice()! 
 private func setup() { commandQueue = device.makeCommandQueue() let textureLoader = MTKTextureLoader(device: device) texture = try! textureLoader.newTexture( name: "highsierra", scaleFactor: view.contentScaleFactor, bundle: nil) mtkView.device = device mtkView.delegate = self mtkView.colorPixelFormat = texture.pixelFormat }
  • 23. this is the Minimumimplementation
  • 24. private let device = MTLCreateSystemDefaultDevice()! 
 private func setup() { commandQueue = device.makeCommandQueue() let textureLoader = MTKTextureLoader(device: device) texture = try! textureLoader.newTexture( name: "highsierra", scaleFactor: view.contentScaleFactor, bundle: nil) mtkView.device = device mtkView.delegate = self mtkView.colorPixelFormat = texture.pixelFormat } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else {return} guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalE guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fa let w = min(texture.width, drawable.texture.width) let h = min(texture.height, drawable.texture.height) blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSizeMake(w, h, texture.depth), to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0)) blitEncoder.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() commandBuffer.waitUntilCompleted() } imageView.image = image
  • 25. private let device = MTLCreateSystemDefaultDevice()! 
 private func setup() { commandQueue = device.makeCommandQueue() let textureLoader = MTKTextureLoader(device: device) texture = try! textureLoader.newTexture( name: "highsierra", scaleFactor: view.contentScaleFactor, bundle: nil) mtkView.device = device mtkView.delegate = self mtkView.colorPixelFormat = texture.pixelFormat } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else {return} guard let commandBuffer = commandQueue.makeCommandBuffer() else {fatalE guard let blitEncoder = commandBuffer.makeBlitCommandEncoder() else {fa let w = min(texture.width, drawable.texture.width) let h = min(texture.height, drawable.texture.height) blitEncoder.copy(from: texture, sourceSlice: 0, sourceLevel: 0, sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0), sourceSize: MTLSizeMake(w, h, texture.depth), to: drawable.texture, destinationSlice: 0, destinationLevel: 0, destinationOrigin: MTLOrigin(x: 0, y: 0, z: 0)) blitEncoder.endEncoding() commandBuffer.present(drawable) commandBuffer.commit() commandBuffer.waitUntilCompleted() } imageView.image = image 💡
  • 26. My Idea: A Metal wrapper class to draw an image ✓ Easy to use as UIImageView ✓ Metal Accelerated “MetalImageView” metalImageView.texture = texture
  • 29. Sample App for the comparison • Render large images in table cells. - 5120 x 3200 (elcapitan.jpg) - 1245 x 1245 (sierra.png)
  • 30. Measuring Code let time1 = CACurrentMediaTime() if isMetal { let metalCell = cell as! MetalTableViewCell metalCell.metalImageView.textureName = name } else { let uikitCell = cell as! TableViewCell uikitCell.uiImageView.image = UIImage(named: name) } let time2 = CACurrentMediaTime() print("time:(time2-time1)") Time Interval Render with UIImageView Render with Metal
  • 31. Results • Metal is 10x - 20x faster! Time to render an image UIImageView 0.4 - 0.6 msec Metal 0.02 - 0.05 msec iPhone 6s
  • 32. Something weird Metal is more lagging, choppy UIImageView Metal
  • 33. Measuring Code let time1 = CACurrentMediaTime() if isMetal { let metalCell = cell as! MetalTableViewCell metalCell.metalImageView.textureName = name } else { let uikitCell = cell as! TableViewCell uikitCell.uiImageView.image = UIImage(named: name) } let time2 = CACurrentMediaTime() print("time:(time2-time1)")
  • 35. 2. CPU creates GPU commands 
 as a command buffer 1. Load image data to memory 
 for GPU (& CPU) 4. GPU processes the commands 3. Push it to GPU
  • 36. let time1 = CACurrentMediaTime() if isMetal { let metalCell = cell as! MetalTableViewCell metalCell.metalImageView.textureName = name } else { let uikitCell = cell as! TableViewCell uikitCell.uiImageView.image = UIImage(named: name) } let time2 = CACurrentMediaTime() print("time:(time2-time1)")
  • 37. 2. CPU creates GPU commands 
 as a command buffer 1. Load image data to memory 
 for GPU (& CPU) 3. Push it to GPU 4. GPU processes the commands NOT Considered!
  • 38. • Measure the time until the GPU processing is completed func draw(in view: MTKView) { // Prepare the command buffer ... // Push the command buffer commandBuffer.commit() // Wait commandBuffer.waitUntilCompleted() // Measure let endTime = CACurrentMediaTime() print(“Time: (endTime - startTime)”) } Fixed measuring code Submit commands to GPU Wait until the GPU processing is completed Calculate the total time
  • 39. Results • Metal is SLOWER !? - Less than 30fps even the best case → My implementation should have problems • UIImageView is fast enough anyways. Time to render an image UIImageView 0.4 - 0.6 msec Metal 40 - 200 msec
  • 40. Why does UIImageView so fast?
  • 41. ※WWDC17 Platforms State of the Unionより UIKit internally uses Metal
  • 42. • UIKit has been updated, and optimized well. • Should use UIKit rather than making a custom UI component with low level APIs (e.g. Metal) unless there is particular reasons it can be better.
  • 43. Point 1: UIKit is optimized well with GPU
  • 44. Point 2: Consider also the GPU, 
 when measuring the performance
  • 45. Why was MetalImageView so slow? What was the problem? (My Metal Wrapper)
  • 47.
  • 48. On CPU On GPU Create command buffers etc.(on CPU) Submit command buffers etc.(on CPU) Process shaders(on GPU)
  • 52. Current processing flow 1. Resize with MPSImageLanczosScale 2. After 1 is completed, call setNeedsDisplay() 3. draw(in:) of MTKViewDelegate is called 4. Render to screen in the draw(in:) Problem
  • 53. The CPU is waiting for the GPU On CPU On GPU
  • 54. Resize Render 2. CPU creates GPU commands 
 as a command buffer 4. GPU processes the commands 3. Push it to GPU
  • 55. FIX: Combined the commands • Encode both commands into a command buffer - Resize - Render • Push the command buffer to a GPU
  • 56. 2. CPU creates GPU commands 
 as a command buffer 4. GPU processes the commands 3. Push it to GPU Resize Render
  • 59. Point 3: Pay attention to the processing flow between CPU and GPU
  • 61.
  • 62. Speculation: Loading textures is the bottleneck(?) 1. Load image data to memory 
 for GPU (& CPU)
  • 63. Measure the time to load textures let startTime = CACurrentMediaTime() textureLoader.newTexture(name: name, scaleFactor: scaleFactor, bundle: nil) { (texture, error) in let endTime = CACurrentMediaTime() print("Time to load (name): (endTime - startTime)") • Results: 20 - 500 msec → It’s the bottleneck!
  • 64. Fix: Cache the loaded textures • UIImage(named:) caches internally, too • “Caching loaded image data” is NOT a Metal/GPU specific idea.
  • 65. Metal/GPU specific point: “Where is the resource?” Memory for GPU (& CPU) private var cachedTextures: [String: MTLTexture] = [:]OK private var cachedImages: [String: UIImage] = [:]NG
  • 67. Point 4: Be careful where the resource is.
  • 68.
  • 70. Today’s Goal • Learn “how to use Metal” • Be conscious the GPU layer through Metal
  • 71. • Compared the graphics rendering performance of Metal to UIImageView → Learned a lot around GPU 1. UIKit is optimized well with GPU. 2. Consider also the GPU, when measuring the performance. 3. Pay attention to the processing flow between CPU and GPU. 4. Be careful where the resource is.