Khi biên dịch đoạn mã sauđiều khiển thứ tự xuất chậm lại đa luồng chương trình
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <mutex>
std::mutex cout_mut;
void task()
{
for(int i=0; i<10; i++)
{
double d=0.0;
for(size_t cnt=0; cnt<200000000; cnt++) d += 1.23456;
std::lock_guard<std::mutex> lg(cout_mut);
std::cout << d << "(Help)" << std::endl;
// std::cout << "(Help)" << d << std::endl;
}
}
int main()
{
std::vector<std::thread> all_t(std::thread::hardware_concurrency());
auto t_begin = std::chrono::high_resolution_clock::now();
for(auto& t : all_t) t = std::thread{task};
for(auto& t : all_t) t.join();
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "Took : " << (t_end - t_begin).count() << std::endl;
}
Dưới MinGW 4.8.1 phải mất khoảng 2,5 giây để thực thi trên hộp của tôi. Đó là khoảng thời gian cần thiết để chỉ thực hiện chức năng task
đơn luồng.
Tuy nhiên, khi tôi bỏ ghi chú dòng ở giữa và do đó nhận xét ra các dòng trước (có nghĩa là, khi tôi trao đổi thứ tự mà d
và "(Help)"
được ghi vào std::cout
) toàn bộ điều giờ đây chỉ mất 8-9 giây.
Giải thích là gì?
Tôi đã kiểm tra lại và phát hiện ra rằng tôi chỉ gặp sự cố với MinGW-build x32-4.8.1-win32-dwarf-rev3
nhưng không phải với MinGW xây dựng x64-4.8.1-posix-seh-rev3
. Tôi có một máy 64-bit. Với trình biên dịch 64 bit, cả hai phiên bản đều mất ba giây. Tuy nhiên, bằng cách sử dụng trình biên dịch 32 bit, vấn đề vẫn còn (và không phải là do sự nhầm lẫn phiên bản gỡ lỗi/phát hành).
thể nó bằng cách nào đó đã xảy ra mà bạn có thời gian nhanh từ bản phát hành bản phát hành và thời gian chậm từ bản dựng gỡ lỗi? Tôi không nhận được bất kỳ sự khác biệt đáng kể nào bằng cách hoán đổi, với gcc 4.7.2/4.8.1, clang 3.2/3.3 (tất cả Linux). Nhưng đối với bản phát hành, tôi nhận được khoảng 2 giây và để gỡ lỗi tôi nhận được khoảng 8. Đáng chú ý là tỷ lệ bạn đang thấy (trên Windows, trên một số máy khác). –
Không, nó không phải là một vấn đề gỡ lỗi/phát hành; vui lòng xem chỉnh sửa của tôi ở trên. –
Có vẻ như một sự khác biệt của x87 fpu cho 32 bit và SSE2 cho 64 bit. Trình biên dịch 32 bit có thể tạo ra các mã lệnh (chậm) x87 của các phép toán 'double'. – yohjp