2016-04-20 13 views
6

Tôi đã chơi xung quanh với bộ lắp ráp nội tuyến của D và SSE, nhưng tìm thấy một cái gì đó tôi không hiểu. Khi tôi cố gắng thêm hai vectơ float4 ngay sau khi khai báo, phép tính là chính xác. Nếu tôi đặt phép tính trong một hàm riêng biệt, tôi nhận được một loạt các nan s.SSE kỳ lạ với chức năng

//function contents identical to code section in unittest 
float4 add(float4 lhs, float4 rhs) 
{ 
    float4 res; 
    auto lhs_addr = &lhs; 
    auto rhs_addr = &rhs; 
    asm 
    { 
     mov RAX, lhs_addr; 
     mov RBX, rhs_addr; 
     movups XMM0, [RAX]; 
     movups XMM1, [RBX]; 

     addps XMM0, XMM1; 
     movups res, XMM0; 
    } 
    return res; 
} 

unittest 
{ 
    float4 lhs = {1, 2, 3, 4}; 
    float4 rhs = {4, 3, 2, 1}; 

    println(add(lhs, rhs)); //float4(nan, nan, nan, nan) 

    //identical code starts here 
    float4 res; 
    auto lhs_addr = &lhs; 
    auto rhs_addr = &rhs; 
    asm 
    { 
     mov RAX, lhs_addr; 
     mov RBX, rhs_addr; 
     movups XMM0, [RAX]; 
     movups XMM1, [RBX]; 

     addps XMM0, XMM1; 
     movups res, XMM0; 
    } //end identical code 
    println(res); //float4(5, 5, 5, 5) 
} 

Lắp ráp có chức năng giống hệt nhau (theo tôi có thể biết) đến this link.

Chỉnh sửa: Tôi đang sử dụng cấu trúc float4 tùy chỉnh (hiện tại, chỉ là mảng của nó) vì tôi muốn có thể có chức năng thêm như float4 add(float4 lhs, float rhs). Đối với thời điểm hiện tại, có kết quả trong một lỗi biên dịch như thế này:

Error: floating point constant expression expected instead of rhs

Lưu ý: Tôi đang sử dụng DMD 2.071.0

+0

Tôi hy vọng bạn sẽ không thực sự sử dụng mã như vậy để thực hiện. Bạn đang buộc trình biên dịch lưu trữ các vectơ vào bộ nhớ, và sau đó lưu trữ các địa chỉ đó vào bộ nhớ. Sau đó, bạn đang viết mã tải các địa chỉ từ bộ nhớ và tải lại các vectơ. (Trong Windows 'vectorcall' ABI, và trong SysV ABI được sử dụng bởi tất cả các hệ thống AMD64 khác, các tham số vectơ được truyền trong các thanh ghi vector). Trong D, IDK nếu 'lhs_addr' thực sự có thể là một thanh ghi, nhưng nó vẫn là một động tác reg-reg vô dụng tốt nhất. Lý tưởng nhất là có một cú pháp để yêu cầu các vectơ trong các regs cụ thể, như GNU C inline asm. –

+0

Tôi đang cố gắng viết kiểu float4 của riêng mình vì 'float4 rhs_vec = [rhs, rhs, rhs, rhs];' không được phép với lỗi trong câu hỏi. Tại thời điểm này tôi đã sao chép một cách cơ bản mã từ liên kết và đã thực hiện một số chỉnh sửa nhỏ (hy vọng) làm cho nó hoạt động trong D. Hiện tại, nó chỉ hoạt động. Tuy nhiên, bạn sẽ làm gì thay cho phần này? Đây chỉ là bước đột phá thứ ba của tôi vào việc lắp ráp, vì vậy mọi sự điều chỉnh sẽ được đánh giá cao. – Straivers

+0

Tôi không biết D, tôi chỉ thấy câu hỏi này vì các thẻ SSE và thẻ nội tuyến asm. Liệu D có bất cứ điều gì giống như Intel C intrinsics? '__m128 my_vec = _mm_add_ps (vec1, vec2);'? Nếu vậy, có thể bạn sẽ làm tốt hơn với điều đó. Nếu cú ​​pháp asm nội tuyến của D bị hạn chế để truyền dữ liệu qua bộ nhớ, không phải đăng ký, thì [nó chỉ hữu ích nếu bạn muốn viết toàn bộ vòng lặp bên trong nó, không phải là một trình bao bọc cho một vài hướng dẫn] (http://stackoverflow.com/ câu hỏi/3323445/sự khác biệt giữa-asm-and-asm/35959859 # 3595985). Nếu nó hỗ trợ các câu lệnh asm kiểu GNU-C, thì hãy sử dụng nó. –

Trả lời

2

Mã của bạn là lạ, những phiên bản của DMD nào bạn sử dụng? Điều này hoạt động như bị xem là:

import std.stdio; 
import core.simd; 

float4 add(float4 lhs, float4 rhs) 
{ 
    float4 res; 
    auto lhs_addr = &lhs; 
    auto rhs_addr = &rhs; 
    asm 
    { 
     mov RAX, lhs_addr; 
     mov RBX, rhs_addr; 
     movups XMM0, [RAX]; 
     movups XMM1, [RBX]; 

     addps XMM0, XMM1; 
     movups res, XMM0; 
    } 
    return res; 
} 

void main() 
{ 
    float4 lhs = [1, 2, 3, 4]; 
    float4 rhs = [4, 3, 2, 1]; 

    auto r = add(lhs, rhs); 
    writeln(r.array); //float4(5, 5, 5, 5) 

    //identical code starts here 
    float4 res; 
    auto lhs_addr = &lhs; 
    auto rhs_addr = &rhs; 
    asm 
    { 
     mov RAX, lhs_addr; 
     mov RBX, rhs_addr; 
     movups XMM0, [RAX]; 
     movups XMM1, [RBX]; 

     addps XMM0, XMM1; 
     movups res, XMM0; 
    } //end identical code 
    writeln(res.array); //float4(5, 5, 5, 5) 
} 
+0

Cảm ơn sự giúp đỡ của bạn, nhưng tôi chỉ nhận ra rằng tôi đã không đưa vào một số thứ trong câu hỏi của mình, chúng đã được thêm vào câu hỏi. – Straivers

+0

@Straivers, Kozzi11 có thực sự trả lời câu hỏi của bạn hay không? – DejanLekic

+0

Không. Hay đúng hơn, anh ta trả lời câu hỏi ban đầu, khiến tôi nhận ra rằng tôi đã nói sai câu hỏi. Một lỗi đã được sửa chữa. – Straivers

Các vấn đề liên quan