Đáng tiếc là đảm bảo sự liên kết tối đa là khó khăn hơn rất nhiều so với nó phải được, và không có các giải pháp đảm bảo AFAIK. Từ GotW blog (Fast Pimpl article):
union max_align {
short dummy0;
long dummy1;
double dummy2;
long double dummy3;
void* dummy4;
/*...and pointers to functions, pointers to
member functions, pointers to member data,
pointers to classes, eye of newt, ...*/
};
union {
max_align m;
char x_[sizeofx];
};
này không đảm bảo được đầy đủ di động, nhưng trong thực tế nó là gần đủ bởi vì có rất ít hoặc không có trên hệ điều hành này sẽ không hoạt động là được mong đợi.
Đó là về 'hack' gần nhất mà tôi biết về điều này.
Có một cách tiếp cận khác mà tôi đã sử dụng cá nhân để phân bổ siêu nhanh. Lưu ý rằng nó là ác, nhưng tôi làm việc trong các lĩnh vực raytracing nơi tốc độ là một trong những biện pháp lớn nhất về chất lượng và chúng tôi hồ sơ mã trên cơ sở hàng ngày. Nó liên quan đến việc sử dụng một bộ cấp phát heap với bộ nhớ được cấp phát trước hoạt động giống như ngăn xếp cục bộ (chỉ cần tăng một con trỏ trên phân bổ và giảm một số trên deallocation).
Tôi sử dụng nó cho Pimpls đặc biệt. Tuy nhiên, chỉ có người cấp phát là không đủ; để một trình phân bổ như vậy hoạt động, chúng ta phải giả định rằng bộ nhớ cho một lớp, Foo, được cấp phát trong một hàm tạo, cùng một bộ nhớ tương tự như vậy được giải quyết chỉ trong destructor, và chính Foo đó được tạo trên stack. Để làm cho nó an toàn, tôi cần một hàm để xem liệu con trỏ 'này' của một lớp có nằm trong ngăn xếp cục bộ để xác định xem chúng ta có thể sử dụng trình phân bổ stack dựa trên đống siêu nhanh của chúng ta hay không.Để làm được điều đó, chúng tôi đã nghiên cứu các giải pháp dành riêng cho hệ điều hành: Tôi đã sử dụng TIBs và TEBs cho Win32/Win64 và đồng nghiệp của tôi đã tìm thấy giải pháp cho Linux và Mac OS X.
Kết quả sau một tuần nghiên cứu cụ thể cho OS phương pháp để phát hiện phạm vi ngăn xếp, yêu cầu căn chỉnh và thực hiện rất nhiều thử nghiệm và lược tả, là một trình cấp phát có thể cấp phát bộ nhớ trong 4 chu kỳ đồng hồ theo tiêu chí đánh dấu của chúng tôi so với khoảng 400 chu kỳ cho malloc/operator new (thử nghiệm của chúng tôi liên quan sự tranh chấp chủ đề để malloc có thể nhanh hơn một chút so với trường hợp đơn luồng, có lẽ là một vài trăm chu kỳ). Chúng tôi đã thêm một chồng đống chủ đề và phát hiện chuỗi nào đang được sử dụng để tăng thời gian lên khoảng 12 chu kỳ, mặc dù khách hàng có thể theo dõi trình phân bổ chuỗi để nhận được phân bổ 4 chu kỳ. Nó đã xóa sạch các điểm phân bổ bộ nhớ dựa trên bản đồ.
Trong khi bạn không phải trải qua tất cả những rắc rối đó, việc viết cấp phát nhanh có thể dễ dàng hơn và thường áp dụng hơn (ví dụ: cho phép số lượng bộ nhớ phân bổ/deallocate được xác định trong thời gian chạy) so với một số thứ như max_align
đây. max_align
rất dễ sử dụng, nhưng nếu bạn đang theo tốc độ phân bổ bộ nhớ (và giả sử bạn đã lược tả mã của mình và tìm thấy điểm nóng trong malloc/free/operator new/delete với những người đóng góp chính trong mã bạn có quyền kiểm soát) , viết phân bổ của riêng bạn thực sự có thể tạo sự khác biệt.
di động trong nội dung gì? cho mỗi trình biên dịch? cho từng hệ điều hành? cho mỗi kiến trúc? –
Chỉ cần di động như trong "được đảm bảo bởi tiêu chuẩn C++ để hoạt động". Tất nhiên, tôi có thể dễ dàng dựa vào kiến thức của riêng tôi về kiến trúc đích và mã hóa liên kết tối đa, nhưng sẽ tốt hơn nếu ngôn ngữ tự cung cấp các công cụ để trả lời câu hỏi này. – jalf
Lưu ý rằng tham số mẫu 'Align' của' std :: aligned_storage 'có đối số mặc định là" căn chỉnh mặc định ", được định nghĩa là" Giá trị của căn chỉnh mặc định sẽ là yêu cầu căn chỉnh nghiêm ngặt nhất đối với bất kỳ đối tượng C++ nào loại có kích thước không lớn hơn 'Len'." Tôi không biết liệu các loại SSE có được coi là "loại đối tượng C++" hay không và thư viện chuẩn VC10 không có đối số mặc định, vì vậy tôi không biết giá trị dự định là gì (Tôi không có bất kỳ Thư viện chuẩn nào khác triển khai trên máy này). –