2010-02-06 17 views
14

Tôi có một trình quản lý bộ nhớ heap phân vùng heap thành các phân đoạn khác nhau dựa trên số lượng bộ xử lý trên hệ thống. Bộ nhớ chỉ có thể được cấp phát trên phân vùng đi kèm với bộ xử lý của chuỗi đang chạy. Điều này sẽ giúp cho phép các bộ vi xử lý khác nhau tiếp tục chạy ngay cả khi hai bộ xử lý khác nhau muốn cấp phát bộ nhớ cùng một lúc, ít nhất là tôi tin.Làm thế nào bạn có thể tìm thấy số bộ xử lý mà một chuỗi đang chạy?

Tôi đã tìm thấy hàm GetCurrentProcessorNumber() cho Windows, nhưng điều này chỉ hoạt động trên Windows Vista trở lên. Có phương pháp nào hoạt động trên Windows XP không?

Ngoài ra, điều này có thể được thực hiện với pthreads trên hệ thống POSIX không?

+0

bạn biết rằng hầu hết các hệ điều hành sẽ lên lịch cùng một chuỗi trên các lõi khác nhau theo thời gian? – PlasmaHH

Trả lời

8

Đối với XP, Google nhanh chóng tiết lộ điều này: https://www.cs.tcd.ie/Jeremy.Jones/GetCurrentProcessorNumberXP.htm Điều này có hữu ích không?

+0

Có, cảm ơn bạn. Điều này dường như hoạt động trên cả Linux và Windows, miễn là nó đang chạy trên nền tảng x86. –

+0

@Patrick Tôi không nghĩ rằng điều này hoạt động trên Linux, chỉ cần XP trong hình thức đó anyway. –

+0

Bản thân ngôn ngữ lắp ráp không phụ thuộc vào hệ điều hành. Đối với sự khác biệt giữa _asm, '__asm__', asm, vv trên các nền tảng và trình biên dịch khác nhau, mà tôi có thể giải quyết. –

9

Từ đầu ra của man sched_getcpu:

NAME 
     sched_getcpu - determine CPU on which the calling thread is running 

SYNOPSIS 
     #define _GNU_SOURCE 
     #include <utmpx.h> 

     int sched_getcpu(void); 

DESCRIPTION 
    sched_getcpu() returns the number of the CPU 
    on which the calling thread is currently executing. 

RETURN VALUE 
    On success, sched_getcpu() returns a non-negative CPU number. 
    On error, -1 is returned and errno is set to indicate the error. 

SEE ALSO 
    getcpu(2) 

Thật không may, đây là Linux cụ thể. Tôi nghi ngờ có một cách di động để làm điều này.

+0

Việc xem xét nhanh tài liệu pthread không tiết lộ bất kỳ cuộc gọi nào là một phần của API phtread thực hiện điều này. – Omnifarious

+0

Cảm ơn Ilia. Mặc dù điều này chỉ hoạt động trên Linux, nó là một cuộc gọi hàm đẹp và sạch. Nếu/khi tôi cần phải cổng đến hạt nhân khác, tôi chỉ có thể thay đổi cuộc gọi chức năng này thành một phiên bản sửa đổi của bộ lắp ráp ở trên. –

0

Thiết kế này có mùi với tôi. Bạn dường như đang làm cho giả định rằng một sợi sẽ vẫn liên kết với một CPU cụ thể. Điều đó không được bảo đảm. Có, một chủ đề có thể thường ở trên một CPU duy nhất, nhưng nó không phải, và cuối cùng chương trình của bạn sẽ có một luồng chuyển mạch của CPU. Nó có thể không xảy ra thường xuyên, nhưng cuối cùng nó sẽ xảy ra. Nếu thiết kế của bạn không tính đến điều này, thì hầu như bạn sẽ gặp phải một số khó khăn để theo dõi lỗi.

Hãy để tôi đặt câu hỏi này, điều gì xảy ra nếu bộ nhớ được cấp phát trên một CPU và được giải phóng trên một CPU khác? Heap của bạn sẽ xử lý như thế nào?

+0

Bộ xử lý giải phóng không quan trọng. Trong mỗi khối, tôi lưu một con trỏ vào phân vùng chính xác. Tôi chỉ gọi hàm một lần cho mỗi phân bổ, vì vậy đây không phải là một vấn đề. Mặc dù chủ đề hiện tại có thể thay đổi bộ vi xử lý, điều này cũng sẽ không dẫn đến bất kỳ vấn đề nào với thiết kế của tôi (theo lý thuyết: P). Heap chính nó vẫn là một heap bị khóa. Vì vậy, nếu hai chủ đề khác nhau muốn phân bổ trên cùng một phân vùng, một chủ đề sẽ bị khóa cho đến khi kết thúc khác. Thiết kế này chỉ giảm thiểu cơ hội mà một bộ xử lý sẽ khóa thực thi của một bộ xử lý khác. –

+0

Vấn đề có lẽ là một luồng có thể di chuyển _while_ phân bổ bộ nhớ. Điều này có thể gây ra một luồng để xác định nó chạy trên CPU # 0, lấy một con trỏ tới heap # 0, sau đó di chuyển đến CPU # 1, sau đó cố gắng cấp phát từ heap # 0. – MSalters

+0

Điều đó là tốt. Heap của tôi là một heap bị khóa chính nó, vì vậy ngay cả khi không có bộ xử lý ma thuật số đen này, nó sẽ làm việc tốt. Tôi đang tối ưu hóa nó để không khóa các bộ xử lý khác có thể hữu ích hơn. Vì vậy, trong trường hợp cả hai bạn đã chỉ ra, một bộ xử lý khác sẽ bị khóa khỏi phân bổ. Điểm chính của thiết kế của tôi, mặc dù, điều này là không có khả năng xảy ra, do đó, do đó đáng để nỗ lực. –

1

Nếu tất cả những gì bạn muốn làm là tránh tranh chấp, bạn không cần biết CPU hiện tại. Bạn chỉ có thể chọn ngẫu nhiên một đống. Hoặc bạn có thể có một đống cho mỗi chủ đề. Mặc dù bạn có thể nhận được nhiều hơn hoặc ít tranh chấp theo cách đó, bạn sẽ tránh được chi phí bỏ phiếu cho CPU hiện tại, điều này có thể có hoặc không đáng kể. Ngoài ra, hãy kiểm tra scalable_allocator của Intel Thread Building Block, có thể đã giải quyết được vấn đề đó tốt hơn bạn.

3

Ngoài câu trả lời Antony Vennard và mã trên trang web trích dẫn, đây là mã mà sẽ làm việc cho Visual C++ x64 cũng (không inline lắp ráp):

DWORD GetCurrentProcessorNumberXP() { 
    int CPUInfo[4]; 
    __cpuid(CPUInfo, 1); 
    // CPUInfo[1] is EBX, bits 24-31 are APIC ID 
    if ((CPUInfo[3] & (1 << 9)) == 0) return -1; // no APIC on chip 
    return (unsigned)CPUInfo[1] >> 24; 
} 

Một cái nhìn ngắn tại thi hành GetCurrentProcessorNumber() trên Win7 x64 cho thấy rằng họ sử dụng một cơ chế khác nhau để có được số bộ xử lý, nhưng trong (một vài) thử nghiệm của tôi kết quả là như nhau cho nhà của tôi-brewn và chức năng chính thức.

+0

Cpuid là một lệnh serializing và cực kỳ tốn kém (nghĩ 1000 chu kỳ). Chắc chắn không phải là một sự lựa chọn phù hợp cho mục đích thảo luận ở đây. Chọn một đống ngẫu nhiên sẽ tốt hơn, giả sử bạn không chi tiêu 1000 chu kỳ trong trình tạo số :-) –

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