Đối ứng 64bit
Bài đăng này đã không được cập nhật trong 3 năm
LỜI MỞ ĐẦU
iPhone5s đã trở thành smart phone đầu tiên trên thế giới sử dụng chip 64bit (A7). Nhiều người cảm thấy hào hứng với thông tin này, còn tôi thì không thấy hào hứng chút nào. “Device 64bit để làm gì cơ chứ !?” “Phải làm sao để tương thích được đây!?”... Đứng trên lập trường của một người phát triển phần mềm (đầy thành kiến và độc đoán ^_^;) tôi sẽ trình bày một vài suy nghĩ của mình như sau.
TẠI SAO LẠI LỰA CHỌN THỜI ĐIỂM NÀY ĐỂ PHÁT TRIỂN 64BIT
Khi mới nghe về việc các device sẽ được 64bit hoá, suy nghĩ của một lập trình viên application có lẽ sẽ là “không còn bị giới hạn dung lượng bộ nhớ RAM là 4GB(2GB) nữa". Mặc dù hiện tại chưa có device nào được thiết kế với bộ nhớ RAM lớn hơn mức đó, nhưng sau này chắc chắn sẽ có những thiết bị (ko chỉ là iPhone) vượt qua ngưỡng đấy, thế nên ngay từ bây giờ có sự chuẩn bị sẽ tốt hơn. Tôi nghĩ đấy có thể là 1 lý do chăng.
Còn nhiều ý kiến khác về nguyên nhân của việc 64bit hoá vào thời điểm hiện tại, các bạn có thể tham khảo ở đây:
Tại sao iphone5s lại sử dụng 64bit ?
Ý nghĩa của việc iOS 7 hỗ trợ 64bit
VIỆC ĐỐI ỨNG VỚI 64BIT CÓ CẦN THIẾT KO ?
Hiện tại thì Apple ko yêu cầu các applications bắt buộc phải đối ứng 64bit, nên việc này vẫn phụ thuộc vào quyết định riêng của từng nhà phát triển. Theo tôi thì nên thực hiện đối ứng 64bit vì vài lý do sau đây:
-
Trong các tài liệu (ví dụ của Apple) có nhắc đến việc cải thiện được performance (tuy nhiên cải thiện ra sao thì cần phải đo đạc cụ thể).
-
Thiết bị sử dụng 64bit khi thực thi binary 32bit sẽ có thể phát sinh 1 số chức năng chạy không đúng:
- Có thể không sử dụng được chức năng nhận diện khuôn mặt (chưa kiểm chứng)
- Xử lý filter của Core Image sẽ không hoạt động khi chỉ định CPU thay vì GPU (đã kiểm chứng ở iOS7.0.4 và iPad Air)
- Khi sử dụng chức năng Bluetooth của GameKit thì sẽ xuất hiện dòng báo lỗi “Bluetooth problem in 32-bit processes on 64-bit system: skipping check" (ko rõ thực tế có phát sinh bug nào ko)
- (Trong trường hợp application mới) Trong tương lai có thể sẽ phải tốn thời gian đối ứng 64bit, vậy thì làm trước ngay từ đầu còn hơn là để sau này lại than thở.
NẾU BUILD 64BIT THÌ CÓ CHẠY ĐƯỢC TRÊN CÁC DEVICE 32BIT KO?
Những application hỗ trợ cả 64bit thì khi build bằng Xcode phải build riêng binary cho 2 trường hợp 32bit/64bit. Apple sử dụng "fat binary" để chứa binary sử dụng cho nhiều CPU khác nhau.
Trong project settings ở Xcode, trong tab「Build Settings」sẽ có mục 「Architectures」để lựa chọn CPU architecture mà project hỗ trợ.
iPhone4S sử dụng armv7, iPhone5 và iPhone5c sử dụng armv7s, còn iPhone5s sử dụng arm64.
Trong trường hợp chỉ định nhiều architectures, ứng với mỗi architecture thì project phải build 1 lần, sau đó bó lại tạo ra 1 binary file (ipa file). Ví dụ như hỗ trợ armv7, armv7s, arm64 thì phải build 3 lần.
Tuy nhiên kể từ iOS 5.1.1 mới hỗ trợ được arm64.
Về CPU Architectures thì nên tham khảo ở những link sau:
CÁC CHÚ Ý KHI ĐỐI ỨNG 64BIT
Trong tài liệu dưới đây đã mô tả đầy đủ các phương án đối ứng cho 64bit nên phần này các bạn chỉ cần đọc lướt qua cũng được: 64-Bit Transition Guide for Cocoa Touch
Tôi cũng chỉ liệt kê một số vấn đề tôi thấy là đáng chú ý nhất:
1. Tổ chức dữ liệu và độ dài của một số kiểu dữ liệu bị thay đổi
Tại thời điểm hiện tại, một chương trình cần hỗ trợ cả 32bit và 64bit, tuy nhiên khi tiến hành trao đổi thông tin giữa các device 32bit - 64bit, hoặc khi trao đổi binary file thông qua iTunes, nếu sử dụng các kiểu dữ liệu có độ dài khác nhau ở 32bit và 64bit thì thực sự là thảm hoạ.
Ví dụ như CGFloat
ở 32bit thì là kiểu float
, nhưng ở 64bit thì lại là kiểu double
. Tất cả các kiểu dữ liệu của CoreGraphics đều không thể đồng nhất được độ dài. CGRect
và CGAffineTransform
đương nhiên cũng không phải là ngoại lệ.
Về cách phòng tránh vấn đề này, nếu thực sự ko cần quan tâm đến độ chính xác về độ dài dữ liệu, thì khi serialization hãy chuyển các giá trị sang kiểu float
.
2. Ko sửa lại open source thì không thể chạy đúng được
typedef long INT32;
Ví dụ trên rõ ràng là đang khai báo số nguyên 32bit nhưng lại sử dụng kiểu long
, khi tiến hành ghi giá trị ra binary file thì chạy trên device 64bit có thể sẽ phát sinh vấn đề.
Nhất định là phải thay thế bằng int
với int32_t
thì mới chính xác được
3. objc_msgSend gây crash
Khi sử dụng objc_msgSend, khi xuất hiện thông báo lỗi [NSObject performSelector:withObject:],
hay khi thiếu tham số thì khi chạy sẽ gây crash. Tuy nhiên chạy bằng simulator lại không bị crash.
Sử dụng cast thì có thể tránh được điều này.
Kết luận
Vì ko nắm rõ về cấu trúc compiler và cấu trúc máy tính nên còn nhiều chỗ tôi viết nhưng không tự tin lắm. Rất mong mọi người chỉ bảo thêm m(_ _)m
All rights reserved