2013-08-26 31 views
5

Tôi đang chuyển một số mã vào các cửa sổ và thấy luồng quá chậm. Nhiệm vụ mất 300 giây trên cửa sổ (với hai xeon E5-2670 8 lõi 2.6ghz = 16 lõi) và 3,5 giây trên Linux (xeon E5-1607 4 lõi 3ghz). Sử dụng biểu thức vs2012.Chuyển chuỗi chủ đề đến cửa sổ. Các phần quan trọng rất chậm

Tôi có 32 chủ đề gọi là EnterCriticalSection(), popping một công việc 80 byte của std :: stack, LeaveCriticalSection và thực hiện một số công việc (tổng cộng 250k công việc).

Trước và sau mỗi phần quan trọng gọi tôi in ID luồng và thời gian hiện tại.

  • Thời gian chờ khóa một chủ đề duy nhất là ~ 160ms
  • Để bật công việc ra khỏi stack mất ~ 3ms
  • Calling nghỉ mất ~ 3ms
  • Công việc mất ~ 1ms

(tương đương với Debug/Release, Debug mất nhiều thời gian hơn. Tôi rất muốn có thể chỉnh sửa đúng mã: P)

Nhận xét cuộc gọi công việc làm cho toàn bộ quá trình mất 2 giây (vẫn còn nhiều hơn linux).

Tôi đã thử cả queryperformancecounter và timeGetTime, cả hai đều cho kết quả tương tự.

AFAIK công việc không bao giờ thực hiện bất kỳ cuộc gọi đồng bộ nào, nhưng tôi không thể giải thích sự chậm trễ trừ khi có.

Tôi không biết tại sao sao chép từ ngăn xếp và nhạc pop mất quá nhiều thời gian. Một điều rất khó hiểu là lý do tại sao một cuộc gọi để lại() mất quá lâu.

Có ai có thể suy đoán về lý do khiến quảng cáo chạy chậm không?

Tôi đã không nghĩ rằng sự khác biệt trong bộ vi xử lý sẽ mang lại hiệu suất 100x khác nhau, nhưng nó có thể liên quan đến CPU kép không? (phải đồng bộ giữa các CPU riêng biệt so với lõi nội bộ).

Nhân tiện, tôi biết std :: thread nhưng muốn mã thư viện của tôi hoạt động với tiền tố C++ 11.

chỉnh sửa

//in a while(hasJobs) loop... 

EVENT qwe1 = {"lock", timeGetTime(), id}; 
events.push_back(qwe1); 

scene->jobMutex.lock(); 

EVENT qwe2 = {"getjob", timeGetTime(), id}; 
events.push_back(qwe2); 

hasJobs = !scene->jobs.empty(); 
if (hasJobs) 
{ 
    job = scene->jobs.front(); 
    scene->jobs.pop(); 
} 

EVENT qwe3 = {"gotjob", timeGetTime(), id}; 
events.push_back(qwe3); 

scene->jobMutex.unlock(); 

EVENT qwe4 = {"unlock", timeGetTime(), id}; 
events.push_back(qwe4); 

if (hasJobs) 
    scene->performJob(job); 

và lớp mutex, với các công cụ Linux #ifdef loại bỏ ...

CRITICAL_SECTION mutex; 

... 

Mutex::Mutex() 
{ 
    InitializeCriticalSection(&mutex); 
} 
Mutex::~Mutex() 
{ 
    DeleteCriticalSection(&mutex); 
} 
void Mutex::lock() 
{ 
    EnterCriticalSection(&mutex); 
} 
void Mutex::unlock() 
{ 
    LeaveCriticalSection(&mutex); 
} 
+0

Bạn đang sử dụng gì trên Linux? Bạn đang bảo vệ chỉ truy cập vào std :: stack với các phần quan trọng? – xanatos

+2

Nơi nào bạn in id luồng và thời gian hiện tại? – avakar

+0

Chọn một ngôn ngữ. Và điều này có vẻ kỳ quặc. Chắc chắn * âm thanh * đủ đơn giản để [SSCCE] (http://www.sscce.org) có thể thực hiện được. Tôi đồng tình với trải nghiệm của mình trên Windows có phần hơi mờ nhạt so với bản phân phối Linux được trang bị tương đối, nhưng điều này thực sự có vẻ là một mớ khá rộng. – WhozCraig

Trả lời

0

Nó có vẻ như các cửa sổ đề bạn đang phải đối mặt siêu tranh. Họ dường như đã được tuần tự hóa hoàn toàn. Bạn có khoảng 7ms tổng thời gian xử lý trong phần quan trọng và 32 luồng. Nếu tất cả các chủ đề được xếp hàng đợi trên khóa, luồng cuối cùng trong hàng đợi sẽ không chạy được cho đến khi sau khi ngủ khoảng 217ms. Đây không phải là quá xa 160ms của bạn quan sát thời gian chờ đợi.

Vì vậy, nếu các chủ đề không có gì khác để làm hơn là nhập phần quan trọng, làm việc, sau đó rời khỏi phần quan trọng, đây là hành vi tôi mong đợi.

Cố gắng mô tả hành vi định cấu hình của Linux và xem liệu hành vi của chương trình có thực sự và táo để so sánh với quả táo hay không.

+0

Tôi đồng ý, có vẻ như họ đang chạy tuần tự lỏng lẻo (đôi khi có sự khác biệt nhỏ trong thứ tự thực hiện). Không có mã để tuần tự hóa chúng, và một bản sao 80 byte và pop nên được WAY WAY nhanh hơn công việc của tôi. Những gì thực sự không có ý nghĩa là thời gian thực hiện để gọi LeaveCriticalSection. Tôi tin rằng serialization là một triệu chứng của một vấn đề tiềm ẩn với các phần quan trọng. Tôi sẽ tăng gấp đôi kiểm tra tranh chấp trên Linux mặc dù. – jozxyqk

1

CRITICAL_SECTION của cửa sổ quay tròn khi bạn lần đầu tiên nhập. Nó không đình chỉ các sợi được gọi là EnterCriticalSection trừ khi một khoảng thời gian đáng kể đã trôi qua trong vòng quay. Vì vậy, có 32 chủ đề cạnh tranh cho cùng một phần quan trọng sẽ đốt cháy và lãng phí rất nhiều chu kỳ CPU. Hãy thử một mutex thay thế (xem CreateMutex).

+3

[Tôi nghi ngờ như vậy] (http://stackoverflow.com/questions/18442574/porting-threads-to-windows-critical-sections-are-very-slow#comment27103010_18442574), nhưng sẽ không điều chỉnh số lượng spin phù hợp/nhanh hơn sử dụng mutex? – dyp

Các vấn đề liên quan