Tôi quan tâm đến hiệu suất của việc chuyển đổi thông điệp và mutex trong gcc mới nhất với các luồng dựa trên pthread và môi trường phát triển Ubuntu. Một vấn đề chung chung tốt cho việc này là các nhà triết học ăn uống, nơi mỗi nhà triết học sử dụng lh và rh ngã ba được chia sẻ với hàng xóm tay trái và bên phải. Tôi tăng số lượng các nhà triết học lên 99 để giữ cho bộ xử lý lõi tứ của tôi bận rộn.Hiệu suất của các chủ đề trong C++ 11
int result = try_lock(forks[lhf], forks[rhf]);
mã trên cho phép nhà triết học của tôi cố gắng lấy hai nhánh mà họ cần ăn cùng.
// if the forks are locked then start eating
if (result == -1)
{
state[j] = philosophers::State::Eating;
eating[j]++;
if (longestWait < waiting[j])
{
longestWait = waiting[j];
}
waiting[j] = 0;
} else {
state[j] = philosophers::State::Thinking;
thinking[j]++;
waiting[j]++;
}
mã ở trên giám sát việc tiến hành ăn uống hoặc suy nghĩ của triết gia của tôi tùy thuộc vào việc họ có giành được hai dĩa hay không.
{
testEnd te(eating[j]+thinking[j]-1);
unique_lock<mutex> lk(cycleDone);
endCycle.wait(lk, te);
}
mã ở trên chờ đợi cho tất cả các nhà triết học để hoàn thành việc lựa chọn sau thời gian này các nhà triết học là miễn phí để thực hiện một nỗ lực mới:
if (philosophers::State::Eating == state[j])
{
state[j] = philosophers::State::Thinking;
forks[lhf].unlock();
forks[rhf].unlock();
}
Tôi có một chủ đề chính theo dõi các triết gia và di chuyển chúng từ một chu kỳ đến chu kỳ tiếp theo cho phép chúng ăn khoảng 10 giây và suy nghĩ nhiều nhất có thể. Kết quả là khoảng 9540 chu kỳ với một số nhà triết học đang đói và có rất nhiều thứ để ăn và rất nhiều thời gian suy nghĩ! Vì vậy, tôi cần phải bảo vệ các nhà triết học của tôi đói và chờ đợi quá lâu nên tôi thêm logic hơn để ngăn chặn hơn ăn bằng cách yêu cầu các triết gia ăn để phát hành và suy nghĩ chứ không phải là GAB dĩa cùng sau khi chia tay rất nhỏ:
// protect the philosopher against starvation
if (State::Thinking == previous)
{
result = try_lock(forks[lhf], forks[rhf]);
}
Bây giờ tôi có 9598 chu kỳ với mỗi nhà triết học nhận được một phần tương đối bằng nhau về ăn uống (2620 - 2681) và suy nghĩ với sự chờ đợi lâu nhất là 14. Không tệ. Nhưng tôi không hài lòng vì vậy bây giờ tôi thoát khỏi tất cả các mutex và ổ khóa và giữ cho nó đơn giản với các nhà triết học thậm chí ăn trong chu kỳ thậm chí và các nhà triết học lẻ ăn trong chu kỳ lẻ. Tôi sử dụng một phương pháp đơn giản để đồng bộ hóa các nhà triết học
while (counter < counters[j])
{
this_thread::yield();
}
Ngăn chặn một nhà triết học ăn hoặc suy nghĩ quá nhiều lần sử dụng bộ đếm chu kỳ toàn cầu. Cùng một khoảng thời gian và các nhà triết học quản lý khoảng 73543 chu kỳ với 36400 khẩu phần ăn và không quá 3 chu kỳ chờ đợi. Vì vậy, thuật toán đơn giản của tôi với không có khóa là cả hai nhanh hơn và có một phân phối tốt hơn của chế biến giữa các chủ đề khác nhau.
Có ai có thể nghĩ ra cách tốt hơn để giải quyết vấn đề này không? Tôi sợ rằng khi tôi thực hiện một hệ thống phức tạp với nhiều luồng mà nếu tôi thực hiện theo các kỹ thuật truyền thông và mutex truyền thống, tôi sẽ kết thúc với quá trình xử lý không cân bằng và cần thiết trên các luồng khác nhau trong hệ thống của mình.
Lịch trình đồng bộ được chọn thủ công được biết là nhịp tối ưu được tạo ngẫu nhiên. Tuyệt quá. Vấn đề ở đâu? –
Đề xuất 'std :: hemlock' cho C++ 1y sẽ kết thúc vấn đề này một lần và cho tất cả. –
Điều này dường như không liên quan gì đến C++ 11 mỗi lần. –