2010-12-12 9 views
12

Truyền các loại hoặc cấu trúc được căn chỉnh với các loại căn chỉnh theo giá trị không hoạt động với một số triển khai. Điều này phá vỡ các container STL, bởi vì một số phương thức (chẳng hạn như thay đổi kích thước) lấy đối số của chúng theo giá trị.Các loại được sắp xếp và đối số truyền theo giá trị

Tôi chạy một số thử nghiệm với Visual Studio 2008 và không hoàn toàn chắc chắn khi nào và cách vượt qua bởi giá trị không thành công. Mối quan tâm chính của tôi là chức năng foo. Nó có vẻ hoạt động tốt, nhưng nó có thể là kết quả của nội tuyến hoặc một số trùng hợp ngẫu nhiên khác không? Nếu tôi đổi chữ ký thành void foo (const __m128 &)?

Thông tin đầu vào của bạn được đánh giá cao. Cảm ơn bạn.

struct A 
{ 
    __m128 x; 
    int n; 
}; 

void foo(__m128); 
void bar(A); 

void f1() 
{ 
    // won't compile 
    // std::vector<A> vec1(3); 

    // compiles, but fails at runtime when elements are accessed 
    std::vector<__m128> vec2(3); 

    // this seems to work. WHY??? 
    std::vector<__m128, some_16_byte_aligned_allocator<__m128> > vec3(3); 

    __m128 x; 
    A a; 

    // passed by value, is it OK? 
    foo(x); 

    // won't compile 
    //bar(a); 
} 

EDIT. STL thất bại ngay cả với phân bổ liên kết, bởi vì vượt qua bởi vấn đề giá trị vẫn còn.

Tìm thấy liên kết này pass __m128 by value

+0

Lỗi biên dịch/cảnh báo bạn nhận được là gì? Tôi giả định một cái gì đó như "thông số chính thức ... sẽ không được liên kết"? – celion

+0

Đây là những gì tôi nhận được. lỗi C2719: 'unnamed-parameter': tham số chính thức với __declspec (align ('16 ')) sẽ không được căn chỉnh – watson1180

+0

Trong x64, đối số hàm hỗ trợ liên kết 16 byte, vì vậy vấn đề này biến mất. Tôi biết điều đó không giải quyết được vấn đề ngay lập tức của bạn, nhưng hey, nó nhẹ hơn không có gì. ;) – jalf

Trả lời

2

Tôi nghĩ rằng cách duy nhất an toàn để thực hiện điều này nói chung là phải vượt qua bằng cách tham khảo. Một số nền tảng (ví dụ: Xbox 360) hỗ trợ truyền các đối số vectơ trong sổ đăng ký, nhưng tôi không nghĩ rằng điều này có thể xảy ra trên x86.

Đối với trường hợp std::vector, bạn sẽ cần đảm bảo rằng bộ nhớ được phân bổ được căn chỉnh đến 16 byte; nếu không bạn sẽ gặp sự cố khi bạn cố gắng thực hiện hầu hết các hoạt động trên các vectơ không thẳng hàng.

Nếu bạn đang hỗ trợ nhiều nền tảng, một kế hoạch an toàn là sử dụng typedef ví dụ:

typedef const MyVector& MyVectorParameter; 

Sau đó, bạn có thể thay đổi typedef trên nền tảng hỗ trợ véc-tơ theo từng giá trị.

+0

Thay thế trợ giúp cấp phát bằng std :: vector <__m128>, nhưng std :: vector vẫn không biên dịch. – watson1180

+0

Bạn đã kiểm tra 'sizeof (A)'? Nếu nó không phải là bội số của 16 byte, thì các phần tử tiếp theo của mảng lưu trữ được phân bổ bởi vectơ sẽ không được căn chỉnh, ngay cả khi phần đầu của bộ nhớ được căn chỉnh. –

+0

Kích thước nền tảng A của tôi là 32 byte.Căn chỉnh sai sẽ gây ra sự cố thời gian chạy, nhưng vector sẽ không biên dịch bất kể phân bổ. – watson1180

1

thường được sử dụng thay đổi kích thước() chức năng là gây ra tất cả các liên kết và có lẽ bạn có thể cố gắng chuyên mẫu vector cho __m128?