Vì nó liên quan đến mã iPhone và lắp ráp sau đó tôi sẽ đưa ra một ví dụ có liên quan trong thế giới iPhone (và không phải một số sse hoặc x86 asm). Nếu ai đó quyết định viết mã lắp ráp cho một số ứng dụng thế giới thực, thì rất có thể đây sẽ là một số loại xử lý tín hiệu số hoặc thao tác hình ảnh. Ví dụ: chuyển đổi không gian màu của pixel RGB, mã hóa hình ảnh sang định dạng jpeg/png hoặc mã hóa âm thanh thành mp3, amr hoặc g729 cho các ứng dụng voip. Trong trường hợp mã hóa âm thanh có nhiều trình dịch không thể dịch bởi trình biên dịch thành mã asm hiệu quả, chúng đơn giản là không tương đương trong C. Ví dụ về các công cụ thường được sử dụng trong xử lý âm thanh: toán học bão hòa, nhân, tích lũy thường trình, nhân ma trận .
Ví dụ về bổ sung bão hòa: 32-bit ký int có phạm vi: 0x8000 0000 < = int32 < = 0x7fff ffff. Nếu bạn thêm hai kết quả ints có thể tràn, nhưng điều này có thể không được chấp nhận trong một số trường hợp nhất định trong xử lý tín hiệu kỹ thuật số. Về cơ bản, nếu kết quả tràn hoặc underflows bão hòa thêm nên trả về 0x8000 0000 hoặc 0x7fff ffff. Đó sẽ là một hàm c đầy đủ để kiểm tra điều đó. một phiên bản tối ưu hóa các add bão hòa có thể là:
int saturated_add(int a, int b)
{
int result = a + b;
if (((a^b) & 0x80000000) == 0)
{
if ((result^a) & 0x80000000)
{
result = (a < 0) ? 0x80000000 : 0x7fffffff;
}
}
return result;
}
bạn cũng có thể làm nhiều if/else để kiểm tra tràn hoặc trên x86, bạn có thể kiểm tra tràn cờ (mà cũng đòi hỏi bạn phải sử dụng asm). iPhone sử dụng cv armv6 hoặc v7 có dsp asm. Vì vậy, hàm saturated_add
với nhiều brunches (if/else statements) và 2 hằng số 32 bit có thể là một lệnh asm đơn giản chỉ sử dụng một chu kỳ CPU. Vì vậy, chỉ cần làm saturated_add để sử dụng lệnh asm có thể làm cho toàn bộ thuật toán nhanh gấp hai đến ba lần (và nhỏ hơn về kích thước). Dưới đây là hướng dẫn QADD: QADD
ví dụ khác về mã mà thường thực hiện trong vòng dài là
res1 = a + b1*c1;
res2 = a + b2*c2;
res3 = a + b3*c3;
có vẻ như không có gì không thể được tối ưu hóa ở đây, nhưng trên ARM cpu bạn có thể sử dụng hướng dẫn dsp cụ thể mất ít chu kỳ hơn để làm phép nhân đơn giản! Đúng vậy, a + b * c với các hướng dẫn cụ thể có thể thực thi nhanh hơn đơn giản * b. Đối với loại trình biên dịch đơn giản này không thể hiểu logic của mã của bạn và không thể sử dụng các hướng dẫn dsp này trực tiếp và đó là lý do tại sao bạn cần viết asm theo cách thủ công để tối ưu hóa mã, NHƯNG bạn chỉ nên viết thủ công một số phần mã cần làm được tối ưu hóa. Nếu bạn bắt đầu viết các vòng đơn giản bằng tay thì hầu như chắc chắn bạn sẽ không đánh bại trình biên dịch! Có nhiều giấy tờ tốt trên web để lắp ráp nội tuyến để mã bộ lọc linh sam, mã hóa/giải mã amr, v.v.
Không chọn bạn, nhưng có rất nhiều người trên SO yêu cầu tối ưu hóa và câu hỏi tốc độ và rất ít nói rằng họ cần nó bởi vì họ không đáp ứng yêu cầu. Rõ ràng chúng ta chưa đánh bại trong "tối ưu hóa sớm là gốc rễ của tất cả các điều ác" thần chú đủ :) –
Điều gì khiến câu hỏi của tôi là tôi đã dicking xung quanh với lắp ráp nội tuyến trên iPhone và sẽ viết một bài đăng blog về nó . Nhưng tôi không thể cho cuộc sống của tôi vượt qua trình biên dịch của tôi. Vì vậy, tôi đã tò mò để xem liệu có trường hợp cạnh được biết đến nơi trình biên dịch sản xuất mã không hiệu quả. –
Lắp ráp ARM là một trong những bộ hướng dẫn "sạch" hơn. Một phần của triết lý của các bộ xử lý RISC là không thêm các lệnh mà trình biên dịch không dễ sử dụng. Bạn sẽ phải xem xét tập lệnh của biến thể ARM cụ thể và tìm mã opcodes không có bản dịch C rõ ràng. – NoMoreZealots