2011-12-23 15 views
7

Tôi đang nghiên cứu về lắp ráp nội tuyến. Tôi muốn viết một thói quen đơn giản trong iPhone theo Xcode 4 LLVM 3.0 Compiler. Tôi thành công viết mã lắp ráp nội tuyến cơ bản.làm thế nào để viết mã lắp ráp nội tuyến về LOOP trong Xcode LLVM?

dụ:

int sub(int a, int b) 
{ 
    int c; 
    asm ("sub %0, %1, %2" : "=r" (c) : "r" (a), "r" (b)); 
    return c; 
} 

Tôi tìm thấy nó trong stackoverflow.com và nó hoạt động rất tốt. Nhưng, tôi không biết cách viết mã về LOOP.

tôi cần phải mã lắp ráp như

void brighten(unsigned char* src, unsigned char* dst, int numPixels, int intensity) 
{ 
    for(int i=0; i<numPixels; i++) 
    { 
     dst[i] = src[i] + intensity; 
    } 
} 
+2

Các chức năng như thế này cũng có thể được triển khai bằng cách sử dụng OpenGL ES và trình đổ bóng phân đoạn. Nếu điều này có thể áp dụng cho vấn đề của bạn. Điều đó sẽ cung cấp cho bạn song song "miễn phí", tương tự như việc sử dụng NEON như Matt đề xuất. – Arne

+0

Bạn chắc chắn có thể sử dụng OpenGL ES cho chắc chắn. Phụ thuộc rất nhiều vào những gì bạn đang làm và nếu bạn muốn kéo nó như một sự phụ thuộc. – mattjgalloway

+0

OpenGL ES có thể không đủ nhanh nếu anh ta cần lấy lại tổng số tính toán cho CPU. GPU của iPad không được sản xuất để thực hiện tác vụ này một cách hiệu quả. – Etan

Trả lời

5

Hãy xem ở đây tại phần vòng lặp - http://en.wikipedia.org/wiki/ARM_architecture

Về cơ bản bạn sẽ muốn một cái gì đó như:

void brighten(unsigned char* src, unsigned char* dst, int numPixels, int intensity) { 
    asm volatile (
        "\t mov r3, #0\n" 
        "Lloop:\n" 
        "\t cmp r3, %2\n" 
        "\t bge Lend\n" 
        "\t ldrb r4, [%0, r3]\n" 
        "\t add r4, r4, %3\n" 
        "\t strb r4, [%1, r3]\n" 
        "\t add r3, r3, #1\n" 
        "\t b Lloop\n" 
        "Lend:\n" 
       : "=r"(src), "=r"(dst), "=r"(numPixels), "=r"(intensity) 
       : "0"(src), "1"(dst), "2"(numPixels), "3"(intensity) 
       : "cc", "r3", "r4"); 
} 

Cập nhật:

An d đây là phiên bản Neon:

void brighten_neon(unsigned char* src, unsigned char* dst, int numPixels, int intensity) { 
    asm volatile (
        "\t mov r4, #0\n" 
        "\t vdup.8 d1, %3\n" 
        "Lloop2:\n" 
        "\t cmp r4, %2\n" 
        "\t bge Lend2\n" 
        "\t vld1.8 d0, [%0]!\n" 
        "\t vqadd.s8 d0, d0, d1\n" 
        "\t vst1.8 d0, [%1]!\n" 
        "\t add r4, r4, #8\n" 
        "\t b Lloop2\n" 
        "Lend2:\n" 
        : "=r"(src), "=r"(dst), "=r"(numPixels), "=r"(intensity) 
        : "0"(src), "1"(dst), "2"(numPixels), "3"(intensity) 
        : "cc", "r4", "d1", "d0"); 
} 

Vì vậy, phiên bản NEON này sẽ làm 8 tại một thời điểm. Tuy nhiên nó không kiểm tra rằng numPixels là chia hết cho 8 vì vậy bạn chắc chắn muốn làm điều đó nếu không mọi thứ sẽ đi sai! Dù sao, nó chỉ là một khởi đầu cho bạn thấy những gì có thể được thực hiện. Lưu ý cùng một số hướng dẫn, nhưng hành động trên tám pixel dữ liệu cùng một lúc. Oh và nó có độ bão hòa trong đó cũng như tôi giả sử bạn sẽ muốn.

+0

các mã này hoạt động rất tốt!nó thực sự hữu ích cho sự hiểu biết của tôi. cảm ơn rất nhiều vì lời khuyên của bạn ~ –

-2

Mặc dù câu trả lời này không trực tiếp là câu trả lời cho câu hỏi của bạn, đó là một lời khuyên chung về việc sử dụng trình biên dịch so với các trình biên dịch hiện đại.

Bạn thường sẽ gặp khó khăn khi đánh bại trình biên dịch về việc tối ưu hóa mã C của bạn. Tất nhiên bằng cách sử dụng thông minh của một số kiến ​​thức về cách dữ liệu của bạn hành xử nó có thể là bạn có thể tinh chỉnh nó chỉ là một vài phần trăm.

Một trong những lý do cho điều này là trình biên dịch hiện đại sử dụng một số kỹ thuật khi xử lý mã như mã bạn mô tả, ví dụ: bỏ vòng lặp, hướng dẫn sắp xếp lại để tránh các gian hàng và bong bóng đường ống, v.v.

Nếu bạn thực sự muốn thuật toán đó, bạn nên xem xét thiết kế lại thuật toán thay vì trong C để tránh chậm trễ nhất. Ví dụ đọc và ghi vào bộ nhớ là tốn kém so với truy cập đăng ký. Một cách để hoàn thành việc này có thể là để mã của bạn tải 4 byte cùng một lúc bằng cách sử dụng unsigned long và sau đó thực hiện toán học này trong sổ đăng ký trước khi ghi 4 byte trở lại trong một hoạt động cửa hàng.

Vì vậy, để tóm tắt lại, hãy làm cho thuật toán của bạn hoạt động thông minh hơn không khó hơn.

+1

Có lẽ anh ấy muốn làm nó như một bài tập trong học tập? Hoặc muốn đảm bảo rằng các chỉ dẫn vectơ từ NEON đang được sử dụng đúng cách? Có vẻ như anh ấy muốn làm công cụ với dữ liệu pixel và chắc chắn có lợi từ một số hướng dẫn vectơ. Bạn có thể thêm và bão hòa 16 pixel tại một thời điểm nếu bạn muốn, ví dụ. – mattjgalloway

+2

Đặc biệt là trên ARM, trình biên dịch chưa ở mức bạn tưởng tượng. Các lệnh SIMD cũng như các thao tác trường bit được tối ưu hóa kém và bạn có thể tăng tốc độ lớn bằng cách mã hóa chúng trực tiếp trong ARM. Tuy nhiên, lưu ý rằng AppStore chỉ chấp nhận các ứng dụng chỉ sử dụng các API được lập tài liệu. Không chắc về cách trình tạo nội tuyến ảnh hưởng đến tính đủ điều kiện của AppStore. – Etan

+0

Lắp ráp nội tuyến không hề ảnh hưởng đến tính đủ điều kiện của App Store. Điều đó không sử dụng API không có giấy tờ. Inline assembly là một chức năng của trình biên dịch/assembler vì vậy nó không có gì để làm với các API của khung công tác. – mattjgalloway