2012-04-07 36 views
8

Có ai có kinh nghiệm với std::async mới thay đổi không? Chúng tôi hiện đang triển khai trình phân tích cú pháp tệp song song, đọc một đoạn tệp và chuyển đoạn này thành một hàm không đồng bộ.Hành vi của GCC với tiêu chuẩn :: async (std :: launch :: async) so với hành vi của Clang

Sử dụng Clang (v3.0) theo cách này hoạt động thực sự tốt với chính sách mặc định std::async (phụ thuộc thực hiện). Trên một máy tính hai lõi, nó cháy lên đến 4 chủ đề những gì hoạt động thực sự tốt.

Nhưng với GCC (v4.7), chuỗi đọc tệp không sinh ra bất kỳ chuỗi mới nào, làm cho chương trình ở cuối hoàn toàn tuần tự.

Sử dụng std::launch::async, cả hai phiên bản đều hoạt động khá giống nhau (trường hợp nào xảy ra).

Có ai biết trạng thái hiện tại của khả năng luồng C++ 11 của GCC không? Hoặc có thể đây là lỗi trong quá trình triển khai của chúng tôi?

đang viết tắt:

while (readNewChunk()) { 
    Chunk &chunk = fileReader_.getChunk(); //reading the file 
    ChunkLoader *chunkLoader = new ChunkLoader(); 
    auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader); 
    dictCreationFutures_.push_back(std::move(ftr)); 
} 
+0

Tôi thực sự khuyên bạn nên sử dụng Boost. Nó sẽ không phải là một bước nhảy lớn để hỗ trợ C++ 11 thích hợp. Các mô hình luồng mới trong C++ 11 yêu cầu bố trí bộ nhớ khác với GCC hoặc MSVC đang sử dụng và chúng không được triển khai thực sự nhiều. –

Trả lời

15

Hành vi nằm trong thông số kỹ thuật, ngay cả khi đó không phải là những gì bạn mong muốn. Nếu bạn không chỉ định chính sách khởi chạy, nó được lấy là async|deferred, điều đó có nghĩa là việc triển khai chính sách sẽ quyết định điều nào. GCC sẽ luôn chọn deferred nếu có lựa chọn.

+0

Cảm ơn bạn đã xóa thông tin đó. Tôi nghĩ rằng tất cả các triển khai hiện tại là một chút "thông minh hơn" và không chỉ làm một _deferred_ đồng bằng. – Bouncner

+4

Tôi cầu xin không đồng ý. Đây là những gì tiêu chuẩn nói (nhấn mạnh mỏ): "Nếu chính sách này được chỉ định cùng với các chính sách khác, chẳng hạn như khi sử dụng giá trị chính sách của' launch :: async | launch :: deferred', việc triển khai sẽ trì hoãn yêu cầu hoặc lựa chọn chính sách _khi không có thêm đồng thời nào có thể được khai thác hiệu quả_. " Điều này là rất khác nhau từ việc tung ra bất kỳ chủ đề mới được hoãn lại. –

5

EDIT2: Tôi sẽ giải thích thêm một chút.

std :: async hứa hẹn một 'tương lai'; đó là: khi bạn muốn nó, nó sẽ ở đó. Nó có thể được tính toán ngay bây giờ, nó có thể được tính toán khi bạn yêu cầu nó, chúng tôi chỉ hứa hẹn nó sẽ xảy ra.

Giống như áp phích bên dưới ghi chú của tôi, GCC mặc định hoãn lại (có nghĩa là, nó sẽ thực hiện lời hứa đó khi được yêu cầu và có thể không phải trước đó). Lý do cho mặc định này là vì GCC không cung cấp hỗ trợ luồng C++ 11 thích hợp. Nó không có bộ lập lịch trình chủ đề nội bộ tốt, trong số rất nhiều thứ khác. Đó là một chút của một hack. Không, giống như một loạt các hack. Trong thực tế, nếu bạn viết mã luồng trong C++ 11 trên GCC, thì nó càng nhiều để khi chúng thực hiện các tính năng, nó sẽ hoạt động đúng; ngay bây giờ, nó chủ yếu hoạt động đúng. Ý tôi là, bạn nhận được kết quả cuối cùng, phải không?

Nếu bạn yêu cầu khởi chạy một chuỗi, nó sẽ là do nó quá ngu ngốc (hiện tại) để nhận ra rằng nó có thể và nên tự nó (không giống như CLang, hiện có bộ lập lịch chuỗi nội bộ tốt hơn).

CHỈNH SỬA: Nghiêm túc? Misinformed down-modding!

Đây là tài liệu tham khảo của tôi! http://gcc.gnu.org/projects/cxx0x.html. Lưu ý hầu như tất cả mọi thứ trong 'đồng thời' bao gồm cả 'mô hình bộ nhớ' được lưu ý là KHÔNG. GCC.GNU.org. Họ là cơ quan có thẩm quyền về GCC mà bạn biết.

Chỉnh sửa một chút từ nhận xét của tôi:

Tôi thực sự khuyên bạn nên sử dụng Boost. Nó sẽ không phải là một bước nhảy lớn để hỗ trợ C++ 11 thích hợp khi GCC sẵn sàng. Các mô hình luồng mới trong C++ 11 yêu cầu bố trí bộ nhớ khác với GCC hoặc MSVC đang sử dụng và chúng chưa được triển khai thực sự nhiều.

+3

Điều gì đã thay đổi trong C++ 11 về "bố cục bộ nhớ"? –

+0

@NicolBolas http://gcc.gnu.org/projects/cxx0x.html. Lưu ý hầu như tất cả mọi thứ trong 'đồng thời' bao gồm 'mô hình bộ nhớ' được lưu ý là NO –

+5

Có, nhưng điều đó không giải thích những gì đã thay đổi với "bộ nhớ * bố trí *". Bố cục là nơi mọi thứ liên quan đến những thứ khác. Bộ nhớ * mô hình * giải thích các quy tắc về khi các biến được truy cập trở nên hiển thị trong các chủ đề khác và như vậy. –

1

Vì vậy, tôi hiểu điều này là 2 năm sau đó, nhưng tôi không thể không cảm thấy cần phải trả lời nhận xét của @ std''OrgnlDave về GCC và CLang, để lưu ý rằng ít nhất hiện tại, tháng 1 năm 2015, cả hai clang phiên bản 3.5 và GCC phiên bản 4.9 có chính xác hành vi tương tự.Hành vi đó là, khi không có chính sách khởi chạy được cung cấp, để mặc định khác, và thực thi khi tương lai :: get được gọi, và chỉ khi chính sách khởi chạy async được cung cấp rõ ràng thì trình biên dịch sẽ dẫn đến thực thi hàm trong nền.