Memset to UnsafeMutablePointer<UInt8> in swift - swift

I have a challenge with a variable with type UnsafeMutablePointer<UInt8>.
I have this working code to alloc and set to zero all an UInt8 array in Swift.
var bits = UnsafeMutablePointer<UInt8>(calloc(width * height, 8))
The problem is I'd like to do it without use the calloc method. I have this code to alloc the array
var bits = UnsafeMutablePointer<UInt8>.alloc(width * height)
but I can't find a method to set to zero all the memory.
I know I can do this, but I don't think is the best way.
for index in 0..< (width * height) {
bits[index] = 0
}

As #matt suggests, you can use initializeFrom to initialize the memory. I would use the Repeat collection type for this, as it avoids any interim allocation:
var bits = UnsafeMutablePointer<UInt8>.alloc(width * height)
bits.initializeFrom(Repeat(count: width * height, repeatedValue: 0))
(note, there’s no need to give the type of the value to Repeat, it can be inferred from the type of bits)
If you find you do this a lot, it might be worth creating a calloc-like extension to UnsafeMutablePointer:
extension UnsafeMutablePointer {
// version that takes any kind of type for initial value
static func calloc(num: Int, initialValue: T) -> UnsafeMutablePointer<T> {
let ptr = UnsafeMutablePointer<T>.alloc(num)
ptr.initializeFrom(Repeat(count: num, repeatedValue: initialValue))
return ptr
}
// convenience version for integer-literal-creatable types
// that initializes to zero of that type
static func calloc<I: IntegerLiteralConvertible>
(num: Int) -> UnsafeMutablePointer<I> {
return UnsafeMutablePointer<I>.calloc(num, initialValue: 0)
}
}
// creates 100 UInt8s initialized to 0
var bits = UnsafeMutablePointer<UInt8>.calloc(100)

You could say:
bits.initializeFrom(Array<UInt8>(count: width * height, repeatedValue: 0))
I'm guessing there's some underlying efficiency to copying the memory this way. But of course there's an inefficiency in that we temporarily make the array. [NOTE: AirspeedVelocity's answer shows a way to avoid that.]
Personally, I liked your original loop best, especially if you write it more compactly, like this:
(0 ..< (width*height)).map {bits[$0] = 0}

Related

Reason why Unsafe Pointers are used in Swift, especially in Metal

I have been looking into potential use cases of UnsafePointer and related UnsafeX in Swift, and am wondering what the use case is i Swift. It sounds like the main use case is performance, but then at the same time types are supposed to offer compiler optimizations and so performance, so I'm not sure when they are actually useful. I would like to know if all things can be refactored to not use them with the same or better performance, or if not, what a specific example with description of the code and perhaps some code or pseudocode that demonstrates how it offers a performance advantage. I would basically like to have a reference of a specific example demoing a performance advantage of unsafe pointers and unsafe stuff.
Some things I've found related to Swift:
However, UnsafePointer is an important API for interoperability and building high performance data structures. - http://atrick.github.io/proposal/voidpointer.html
But typing allows for compiler optimizations. I'm wondering what advantages using the Unsafe features gives you.
True Unsafe Code Performance
https://nbsoftsolutions.com/blog/high-performance-unsafe-c-code-is-a-lie
https://www.reddit.com/r/csharp/comments/67oi9p/can_anyone_enlighten_me_on_why_unsafe_code_is/
https://medium.com/#vCabbage/go-are-pointers-a-performance-optimization-a95840d3ef85
Some places you see the use of this is in Metal code, such as here:
// Create buffers used in the shader
guard let uniformBuffer = device.makeBuffer(length: MemoryLayout<Uniforms>.stride) else { throw Error.failedToCreateMetalBuffer(device: device) }
uniformBuffer.label = "me.dehesa.metal.buffers.uniform"
uniformBuffer.contents().bindMemory(to: Uniforms.self, capacity: 1)
// or here
let ptr = uniformsBuffer.contents().assumingMemoryBound(to: Uniforms.self)
ptr.pointee = Uniforms(modelViewProjectionMatrix: modelViewProjectionMatrix, modelViewMatrix: modelViewMatrix, normalMatrix: normalMatrix)
I don't really understand what's going on with the pointers too well yet, but I wanted to ask to see if these use cases offer performance enhancements or if they could be refactored to use a safe version that had similar or even better performance.
Saw it here too:
func setBit(_ index: Int, value: Bool, pointer: UnsafeMutablePointer<UInt8>) {
let bit: UInt8 = value ? 0xFF : 0
pointer.pointee ^= (bit ^ pointer.pointee) & (1 << UInt8(index))
}
More metal:
uniforms = UnsafeMutableRawPointer(uniformBuffer.contents()).bindMemory(to:GUniforms.self, capacity:1)
vertexBuffer = device?.makeBuffer(length: 3 * MemoryLayout<GVertex>.stride * 6, options: .cpuCacheModeWriteCombined)
vertices = UnsafeMutableRawPointer(vertexBuffer!.contents()).bindMemory(to:GVertex.self, capacity:3)
vertexBuffer1 = device?.makeBuffer(length: maxCount * maxCount * MemoryLayout<GVertex>.stride * 4, options: .cpuCacheModeWriteCombined)
vertices1 = UnsafeMutableRawPointer(vertexBuffer1!.contents()).bindMemory(to:GVertex.self, capacity: maxCount * maxCount * 4)
Stuff regarding images:
func mapIndicesRgba(_ imageIndices: Data, size: Size2<Int>) -> Data {
let palette = self
var pixelData = Data(count: size.area * 4)
pixelData.withUnsafeMutableBytes() { (pixels: UnsafeMutablePointer<UInt8>) in
imageIndices.withUnsafeBytes { (indices: UnsafePointer<UInt8>) in
var pixel = pixels
var raw = indices
for _ in 0..<(size.width * size.height) {
let colorIndex = raw.pointee
pixel[0] = palette[colorIndex].red
pixel[1] = palette[colorIndex].green
pixel[2] = palette[colorIndex].blue
pixel[3] = palette[colorIndex].alpha
pixel += 4
raw += 1
}
}
}
return pixelData
}
Stuff regarding input streams:
fileprivate extension InputStream {
fileprivate func loadData(sizeHint: UInt) throws -> Data {
let hint = sizeHint == 0 ? BUFFER_SIZE : Int(sizeHint)
var buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: hint)
var totalBytesRead = read(buffer, maxLength: hint)
while hasBytesAvailable {
let newSize = totalBytesRead * 3 / 2
// Ehhhh, Swift Foundation's Data doesnt have `increaseLength(by:)` method anymore
// That is why we have to go the `realloc` way... :(
buffer = unsafeBitCast(realloc(buffer, MemoryLayout<UInt8>.size * newSize), to: UnsafeMutablePointer<UInt8>.self)
totalBytesRead += read(buffer.advanced(by: totalBytesRead), maxLength: newSize - totalBytesRead)
}
if streamStatus == .error {
throw streamError!
}
// FIXME: Probably should use Data(bytesNoCopy: .. ) instead, but will it deallocate the tail of not used buffer?
// leak check must be done
let retVal = Data(bytes: buffer, count: totalBytesRead)
free(buffer)
return retVal
}
}
http://metalkit.org/2017/05/26/working-with-memory-in-metal-part-2.html
Swift semantics allows it to make copies of certain data types for safety when reading and potentially writing non-atomic-sized chunks of memory (copy-on-write allocations, etc.). This data copy operation possibly requires a memory allocation, which potentially can cause a lock with unpredictable latency.
An unsafe pointer can be used to pass a reference to a (possibly)mutable array (or block of bytes), or slice thereof, that should not be copied, no matter how (unsafely) accessed or passed around between functions or threads. This potentially reduces the need for the Swift runtime to do as many memory allocations.
I had one prototype iOS application where Swift was spending significant percentages of CPU (and likely the user’s battery life) allocating and copying multi-megabyte-sized slices of regular Swift arrays passed to functions at a very high rate, some mutating, some not mutating them (for near-real-time RF DSP analysis). A large GPU texture, sub-texture-slice accessed each frame refresh, possibly could have similar issues. Switching to unsafe pointers referencing C allocations of memory stopped this performance/battery waste in my vanilla Swift prototype (the extraneous allocate and copy operations disappeared from the performance profiling).

Swift 3: How to check the type of a generic array

I declare a generic array
fileprivate var array: [T?]
I have a method average(), which will calculate average if 'T' is Int or Float; otherwise returns 0
public func average() -> Float {
var mean = 0
if T is Int or Float {
for index in (0..<array.count-1){
mean = mean+array[index]
}
mean = mean/array.count
}
return mean;
}
Question: How will I check if array is holding Int/Float (if T is Int or Float, in above code)
This is a tool for protocols. The useful protocols for your problem are FloatingPoint to handle floating point types (like Float) and Integer to handle signed integer types (like Int). These have slightly different implementations, so it's best to write each one separately. Doing this will ensure that this method is only available for appropriate types of T (rather than all possible types, and just returning 0 in those cases).
extension MyStruct where T: FloatingPoint {
func average() -> T {
let sum = array.flatMap{$0}.reduce(0, +)
let count = T(array.count)
return sum.divided(by: count)
}
}
extension MyStruct where T: Integer {
func average() -> Float {
let sum = array.flatMap{$0}.reduce(0, +)
let count = array.count
return Float(sum.toIntMax()) / Float(count.toIntMax())
}
}
EDIT: Following up a bit more on Caleb's comments below, you may be tempted to think it's ok to just convert integers into floats to generate their average. But this is not safe in general without careful consideration of your ranges. For example, consider the average of [Int.min, Int.max]. That's [-9223372036854775808, 9223372036854775807]. The average of that should be -0.5, and that's what's returned by my example above. However, if you convert everything to floats in order to sum it, you'll get 0, because Float cannot express Int.max precisely. I've seen this bite people in live code when they do not remember that for very large floats, x == x+1.
Float(Int.max) == Float(Int.max - 1) // true
You can use the type method introduced in Swift 3 in the following way:
let type = type(of: array)
print("type: \(type)") // if T is String, you will see Array<Optional<String>> here
You will need to iterate over your array and use "if let" to unwrap the type of the values in the array. If they are ints handle them one way, if they are floats handle them another way.
//while iterating through your array check your elements to see if they are floats or ints.
if let stringArray = T as? Int {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
Here's a high level description:
... inside a loop which allows indexing
if let ex = array[index] as? Int {
your code
continue // go around the loop again, you're all done here
}
if let ex = array[index] as? Float {
// other code
continue // go around the loop again, you're all done here
}
// if you got here it isn't either of them
// code to handle that
... end of inside the loop
I can explain further if that isn't clear enough.
This is probably the simplest way to do it:
var average: Float {
let total = array.reduce(0.0) { (runningTotal, item) -> Float in
if let itemAsFloat = item as? Float {
return runningTotal + itemAsFloat
}
else if let itemAsInt = item as? Int {
return runningTotal + Float(itemAsInt)
}
else {
return runningTotal
}
}
return total / Float(array.count)
}
Obviously if you want it can be a function and depending on how you're wanting to use it you may need to tweak it.
*Note that it's possible to have both Int and Float in an array of T. e.g. if T is Any.

Get the size (in bytes) of an object on the heap

I'm aware you can use MemoryLayout<T>.size to get the size of a type T.
For example: MemoryLayout<Int32>.size // 4
However, for class instances (objects), MemoryLayout<T>.size returns the size of the reference to the object (8 bytes on 64 bit machines), not the size of the actual objects on the heap.
class ClassA { // Objects should be at least 8 bytes
let x: Int64 = 0
}
class ClassB {// Objects should be at least 16 bytes
let x: Int64 = 0
let y: Int64 = 0
}
MemoryLayout<ClassA>.size // 8
MemoryLayout<ClassB>.size // 8, as well :(
How can I get the size of the objects themselves?
For those wondering, I have no real need for this, I'm just exploring around Swift and its interoperability with C.
One option on Apple platforms, because Swift classes are currently built on top of Objective-C classes there, would be to use the Obj-C runtime function class_getInstanceSize, which gives you the size in bytes of an instance of the class, including any padding.
// on a 64-bit machine (1 word == 8 bytes)...
import Foundation
class C {}
print(class_getInstanceSize(C.self)) // 16 bytes metadata for empty class
// (isa ptr + ref count)
class C1 {
var i = 0
var i1 = 0
var b = false
}
print(class_getInstanceSize(C1.self)) // 40 bytes
// (16 metadata + 24 ivars, 8 for i + 8 for i1 + 1 for b + 7 padding)
As far as I tested in the Playground, this function returns seemingly significant value:
func heapSize(_ obj: AnyObject) -> Int {
return malloc_size(Unmanaged.passUnretained(obj).toOpaque())
}
class MyClass {
//no properites...
}
let myObj = MyClass()
print(heapSize(myObj)) //->16
class MyBiggerClass {
var str: String?
var i: Int = 0
}
let myBiggerObj = MyBiggerClass()
print(heapSize(myBiggerObj)) //->64
Seems the current Swift runtime uses malloc-compatible something to allocate memory in heap. (malloc gives some padding to fit the allocated size to power to 2, when allocating small chunks. So, the actually needed size for the instance may be smaller than the malloc_size.)
I haven't tested how far this would work, and undocumented behaviours just depending on the current implementation would change at any time in the future without any notifications.
But if you actually know that, this can be a good starting point for exploration.

How to create a type that either hold an `Array<Int>` or `UnsafePointer<UInt8>`

I'm doing some performance testing of Swift vs Objective-C.
I created a Mac OS hybrid Swift/Objective-C project that creates large arrays of prime numbers using either Swift or Objective-C.
It's got a decent UI and shows the results in a clear display. You can check out the project on Github if you're interested. It's called SwiftPerformanceBenchmark.
The Objective-C code uses a malloc'ed C array of ints, and the Swift code uses an Array object.
The Objective C code is therefore a lot faster.
I've read about creating an Array-like wrapper around a buffer of bytes using code like this:
let size = 10000
var ptr = UnsafePointer<Int>malloc(size)
var bytes = UnsafeBufferPointer<Int>(start: ptr, count: data.length)
I'd like to modify my sample program so I can switch between my Array<Int> storage and using an UnsafeBufferPointer<Int> at runtime with a checkbox in the UI.
Thus I need a base type for my primes array that will hold either an Array<Int> or an UnsafeBufferPointer<Int>. I'm still too weak on Swift syntax to figure out how to do this.
For my Array- based code, I'll have to use array.append(value), and for the UnsafeBufferPointer<Int>, which is pre-filled with data, I'll use array[index]. I guess if I have to I could pre-populate my Array object with placeholder values so I could use array[index] syntax in both cases.
Can somebody give me a base type that can hold either an Array<Int> or an UnsafeBufferPointer<Int>, and the type-casts to allocate either type at runtime?
EDIT:
Say, for example, I have the following:
let count = 1000
var swiftArray:[Int]?
let useSwiftArrays = checkbox.isChecked
typealias someType = //A type that lets me use either unsafeArray or swiftArray
var primesArray: someType?
if useSwiftArrays
{
//Create a swift array version
swiftArray [Int](count: count, repeatedValue: 0)
primesArray = someType(swiftArray)
}
else
{
var ptr = UnsafePointer<Int>malloc(count*sizeof(Int))
var unsafeArray = UnsafeBufferPointer<Int>(start: ptr, count: data.length)
primesArray = someType(unsafeArray)
}
if let requiredPrimes = primesArray
{
requiredPrimes[0] = 2
}
#MartinR's suggestion should help get code that can switch between the two. But there's a shortcut you can take to prove whether the performance difference is between Swift arrays and C arrays, and that's to switch the Swift compiler optimization to -Ounchecked. Doing this eliminates the bounds checks on array indices etc that you would be doing manually by using unsafe pointers.
If I download your project from github and do that, I find that the Objective-C version is twice as fast as the Swift version. But... that’s because sizeof(int) is 4, but sizeof(Int) is 8. If you switch the C version to use 8-byte arithmetic as well...
p.s. it works the other way around as well, if I switch the Swift code to use UInt32, it runs at 2x the speed.
OK, it’s not pretty but here is a generic function that will work on any kind of collection, which means you can pass in either an Array, or an UnsafeMutableBufferPointer, which means you can use it on a malloc’d memory range, or using the array’s .withUnsafeMutableBufferPointer.
Unfortunately, some of the necessities of the generic version make it slightly less efficient than the non-generic version when used on an array. But it does show quite a nice performance boost over arrays in -O when used with a buffer:
func storePrimes<C: MutableCollectionType where C.Generator.Element: IntegerType>(inout store: C) {
if isEmpty(store) { return }
var candidate: C.Generator.Element = 3
var primeCount = store.startIndex
store[primeCount++] = 2
var isPrime: Bool
while primeCount != store.endIndex {
isPrime = true
var oldPrimeCount = store.startIndex
for oldPrime in store {
if oldPrimeCount++ == primeCount { break }
if candidate % oldPrime == 0 { isPrime = false; break }
if candidate < oldPrime &* oldPrime { isPrime = true; break }
}
if isPrime { store[primeCount++] = candidate }
candidate = candidate.advancedBy(2)
}
}
let totalCount = 2_000_000
var primes = Array<CInt>(count: totalCount, repeatedValue: 0)
let startTime = CFAbsoluteTimeGetCurrent()
storePrimes(&primes)
// or…
primes.withUnsafeMutableBufferPointer { (inout buffer: UnsafeMutableBufferPointer<CInt>) -> Void in
storePrimes(&buffer)
}
let now = CFAbsoluteTimeGetCurrent()
let totalTime = now - startTime
println("Total time: \(totalTime), per second: \(Double(totalCount)/totalTime)")
I am not 100% sure if I understand your problem correctly, but perhaps
this goes into the direction that you need.
Both Array and UnsafeMutablePointer conform to MutableCollectionType (which requires a subscript getter and setter).
So this function would accept both types:
func foo<T : MutableCollectionType where T.Generator.Element == Int, T.Index == Int>(inout storage : T) {
storage[0] = 1
storage[1] = 2
}
Example with buffer pointer:
let size = 2
var ptr = UnsafeMutablePointer<Int>(malloc(UInt(size * sizeof(Int))))
var buffer = UnsafeMutableBufferPointer<Int>(start: ptr, count: size)
foo(&buffer)
for elem in buffer {
println(elem)
}
Example with array:
var array = [Int](count: 2, repeatedValue: 0)
foo(&array)
for elem in array {
println(elem)
}
For non-mutating functions you can use CollectionType
instead of MutableCollectionType.

Swift: How to use sizeof?

In order to integrate with C API's while using Swift, I need to use the sizeof function. In C, this was easy. In Swift, I am in a labyrinth of type errors.
I have this code:
var anInt: Int = 5
var anIntSize: Int = sizeof(anInt)
The second line has the error "'NSNumber' is not a subtype of 'T.Type'". Why is this and how do I fix it?
Updated for Swift 3
Be careful that MemoryLayout<T>.size means something different than sizeof in C/Obj-C. You can read this old thread https://devforums.apple.com/message/1086617#1086617
Swift uses an generic type to make it explicit that the number is known at compile time.
To summarize, MemoryLayout<Type>.size is the space required for a single instance while MemoryLayout<Type>.stride is the distance between successive elements in a contiguous array. MemoryLayout<Type>.stride in Swift is the same as sizeof(type) in C/Obj-C.
To give a more concrete example:
struct Foo {
let x: Int
let y: Bool
}
MemoryLayout<Int>.size // returns 8 on 64-bit
MemoryLayout<Bool>.size // returns 1
MemoryLayout<Foo>.size // returns 9
MemoryLayout<Foo>.stride // returns 16 because of alignment requirements
MemoryLayout<Foo>.alignment // returns 8, addresses must be multiples of 8
Use sizeof as follows:
let size = sizeof(Int)
sizeof uses the type as the parameter.
If you want the size of the anInt variable you can pass the dynamicType field to sizeof.
Like so:
var anInt: Int = 5
var anIntSize: Int = sizeof(anInt.dynamicType)
Or more simply (pointed out by user102008):
var anInt: Int = 5
var anIntSize: Int = sizeofValue(anInt)
Swift 3 now has MemoryLayout.size(ofValue:) which can look up the size dynamically.
Using a generic function that in turn uses MemoryLayout<Type> will have unexpected results if you e.g. pass it a reference of protocol type. This is because — as far as I know — the compiler then has all the type information it needs to fill in the values at compile time, which is not apparent when looking at the function call. You would then get the size of the protocol, not the current value.
In Xcode 8 with Swift 3 beta 6 there is no function sizeof (). But if you want, you can define one for your needs. This new sizeof function works as expected with an array. This was not possible with the old builtin sizeof function.
let bb: UInt8 = 1
let dd: Double = 1.23456
func sizeof <T> (_ : T.Type) -> Int
{
return (MemoryLayout<T>.size)
}
func sizeof <T> (_ : T) -> Int
{
return (MemoryLayout<T>.size)
}
func sizeof <T> (_ value : [T]) -> Int
{
return (MemoryLayout<T>.size * value.count)
}
sizeof(UInt8.self) // 1
sizeof(Bool.self) // 1
sizeof(Double.self) // 8
sizeof(dd) // 8
sizeof(bb) // 1
var testArray: [Int32] = [1,2,3,4]
var arrayLength = sizeof(testArray) // 16
You need all versions of the sizeof function, to get the size of a variable and to get the correct size of a data-type and of an array.
If you only define the second function, then sizeof(UInt8.self) and sizeof(Bool.self) will result in "8". If you only define the first two functions, then sizeof(testArray) will result in "8".
Swift 4
From Xcode 9 onwards there is now a property called .bitWidth, this provides another way of writing sizeof: functions for instances and integer types:
func sizeof<T:FixedWidthInteger>(_ int:T) -> Int {
return int.bitWidth/UInt8.bitWidth
}
func sizeof<T:FixedWidthInteger>(_ intType:T.Type) -> Int {
return intType.bitWidth/UInt8.bitWidth
}
sizeof(UInt16.self) // 2
sizeof(20) // 8
But it would make more sense for consistency to replace sizeof: with .byteWidth:
extension FixedWidthInteger {
var byteWidth:Int {
return self.bitWidth/UInt8.bitWidth
}
static var byteWidth:Int {
return Self.bitWidth/UInt8.bitWidth
}
}
1.byteWidth // 8
UInt32.byteWidth // 4
It is easy to see why sizeof: is thought ambiguous but I'm not sure that burying it in MemoryLayout was the right thing to do. See the reasoning behind the shifting of sizeof: to MemoryLayout here.