Cách sử dụng 100% CPU từ chương trình C


79

Đây là một câu hỏi khá thú vị vì vậy hãy để tôi đặt bối cảnh. Tôi làm việc tại Bảo tàng Máy tính Quốc gia và chúng tôi vừa tìm được một siêu máy tính Cray Y-MP EL từ năm 1992 đang chạy và chúng tôi thực sự muốn xem nó có thể chạy nhanh đến mức nào!

Chúng tôi quyết định cách tốt nhất để làm điều này là viết một chương trình C đơn giản sẽ tính toán các số nguyên tố và cho biết mất bao lâu để làm như vậy, sau đó chạy chương trình trên một máy tính để bàn hiện đại nhanh và so sánh kết quả.

Chúng tôi đã nhanh chóng đưa ra mã này để đếm các số nguyên tố:

Tính năng nào trên máy tính xách tay lõi kép chạy Ubuntu (Cray chạy UNICOS) của chúng tôi, hoạt động hoàn hảo, sử dụng 100% CPU và mất khoảng 10 phút hoặc lâu hơn. Khi về nhà, tôi quyết định dùng thử trên PC chơi game hiện đại lõi sáu của mình và đây là nơi chúng tôi nhận được các vấn đề đầu tiên.

Lần đầu tiên tôi điều chỉnh mã để chạy trên Windows vì đó là những gì PC chơi game đang sử dụng, nhưng rất buồn khi thấy rằng quá trình này chỉ nhận được khoảng 15% sức mạnh của CPU. Tôi nhận ra rằng Windows phải là Windows, vì vậy tôi khởi động vào Live CD của Ubuntu với suy nghĩ rằng Ubuntu sẽ cho phép quá trình chạy với toàn bộ tiềm năng của nó như nó đã làm trước đó trên máy tính xách tay của tôi.

Tuy nhiên tôi chỉ nhận được 5% sử dụng! Vì vậy, câu hỏi của tôi là, làm thế nào tôi có thể điều chỉnh chương trình để chạy trên máy chơi game của mình trong Windows 7 hoặc Linux trực tiếp ở mức sử dụng 100% CPU? Một điều khác sẽ tuyệt vời nhưng không cần thiết là nếu sản phẩm cuối cùng có thể là một .exe có thể dễ dàng phân phối và chạy trên các máy Windows.

Cảm ơn rất nhiều!

PS Tất nhiên chương trình này không thực sự hoạt động với bộ vi xử lý chuyên dụng Crays 8, và đó là một vấn đề hoàn toàn khác ... Nếu bạn biết bất cứ điều gì về tối ưu hóa mã để hoạt động trên các siêu máy tính Cray của 90, hãy cho chúng tôi biết!


8
Tôi không thể tin rằng không có một thẻ unicos . ;)
Edward Thomson

32
Đó là một điều kỳ lạ rằng chương trình chủ đề duy nhất này mất 100% sử dụng CPU trên DUAL CORE xử lý)))
mikithskegg

24
Tôi có phải là người duy nhất không thấy câu hỏi này thú vị chút nào không? Hãy đến một, chạy một chương trình đơn luồng trên một máy n-core và hỏi lý do tại sao nó sử dụng 1 / n của các CPU chỉ là ... đừng bận tâm, tôi chỉ downvote :-)
Gunther Piez

16
@drhirsch Chà, câu hỏi cho thấy nỗ lực nghiên cứu. Tôi đã +1 điều đó - ngay cả khi OP đang thiếu điều gì đó cơ bản về tính toán đa lõi.
Mysticial

9
@drhirsch Có rất nhiều câu hỏi không thú vị trên trang web. Tuy nhiên, thú vị hay không là do chủ quan. Anh ta có thể thiếu các nguyên tắc cơ bản và đó không phải là chủ quan. Giống như Mystical đã nói, nó cho thấy nỗ lực nghiên cứu và không dễ trả lời như nó sẽ xuất hiện.
Carl

Câu trả lời:


81

Nếu bạn muốn 100% CPU, bạn cần sử dụng nhiều hơn 1 lõi. Để làm điều đó, bạn cần nhiều chủ đề.

Đây là phiên bản song song sử dụng OpenMP:

Tôi đã phải tăng giới hạn để 1000000làm cho nó mất hơn 1 giây trên máy của tôi.

Đầu ra:

Máy này đã tính toán tất cả 78498 số nguyên tố dưới 1000000 trong 29,753 giây

Đây là 100% CPU của bạn:

nhập mô tả hình ảnh ở đây


1
@ cha0site Vâng, tôi chủ yếu trả lời câu hỏi cho máy chơi game. Chắc chắn có nhiều cách thú vị hơn để gắn CPU. Một trong những điểm chuẩn khét tiếng hơn mà tôi đã thực hiện là câu trả lời của tôi cho câu hỏi này - điều này đã làm quá nóng 2 trong số 4 máy tôi đã kiểm tra.
Mysticial

1
@Mystical Offtopic: Bạn đang chạy phần cứng nào? Hex-Core AMD @ 3.2Ghz của tôi đã làm được điều đó trong 92 giây ...
bag-man

1
@Owen: Anh ấy có Core i7 2600K ... Tôi ghen tị.
cha0site

19
Mặc dù! Quá ... nhiều ... hồng!
Mateen Ulhaq

2
@MohammadFadin en.wikipedia.org/wiki/Parallel_computing Về cơ bản, bạn cần có thể xử lý song song nhiều tác vụ để có thể sử dụng máy tính đa lõi.
Mysticial

24

Bạn đang chạy một quy trình trên máy đa lõi - vì vậy nó chỉ chạy trên một lõi.

Giải pháp này khá dễ dàng, vì bạn chỉ đang cố gắn bộ xử lý - nếu bạn có N lõi, hãy chạy chương trình của bạn N lần (tất nhiên là song song).

Thí dụ

Đây là một số mã chạy NUM_OF_CORESsong song thời gian chương trình của bạn . Đó là mã POSIXy - nó sử dụng fork- vì vậy bạn nên chạy nó trong Linux. Nếu những gì tôi đang đọc về Cray là chính xác, thì việc chuyển mã này có thể dễ dàng hơn so với mã OpenMP trong câu trả lời khác.

Đầu ra


À đại loại là khi bạn cần chạy Prime95, bạn có nhiều trường hợp của nó ... Chắc chắn có một cách để một quá trình sử dụng nhiều lõi? Giống như các chương trình bẻ khóa hàm băm.
bag-man

Chà, một quy trình có thể sử dụng các luồng để thực hiện đa xử lý, nhưng tôi không nghĩ đó là ý của bạn vì một luồng gần như là một quy trình riêng biệt trong ngữ cảnh này. Những gì chúng ta thực sự đang nói ở đây là "người đứng đầu thực thi", có thể là các luồng hoặc quy trình. Vì vậy, không, không có cách nào để làm cho một chương trình đơn luồng chạy trên nhiều lõi, bạn phải viết lại nó. Và đôi khi nó thực sự khó. Và đôi khi nó thực sự không thể.
cha0site

Chà, tôi đoán sẽ không khó bằng việc đưa chương trình hoạt động cho Cray. Xem xét tôi còn khá mới với điều này (Điều gì đã cho tôi đi: P) đâu sẽ là một nơi tốt để bắt đầu?
bag-man

@Owen: Chà, có UNICOSvẻ như nó hơi giống với Unix (dù sao thì Wikipedia cũng nghĩ như vậy), vì vậy nó có thể có fork(). Tôi nghĩ bạn nên học cách sử dụng nó.
cha0site

2
Ồ! Đã +1 bây giờ khi bạn có ví dụ. :)
Mysticial

7

chúng tôi thực sự muốn xem nó có thể đi nhanh như thế nào!

Thuật toán tạo số nguyên tố của bạn rất kém hiệu quả. So sánh nó với primegen mà tạo ra các số nguyên tố 50847534 lên đến 1000000000 trong vòng 8 giây trên Pentium II-350.

Để tiêu thụ tất cả các CPU một cách dễ dàng, bạn có thể giải quyết một vấn đề song song đáng xấu hổ , chẳng hạn như tính toán bộ Mandelbrot hoặc sử dụng lập trình di truyền để vẽ Mona Lisa trong nhiều luồng (quy trình).

Một cách tiếp cận khác là sử dụng một chương trình điểm chuẩn hiện có cho siêu máy tính Cray và chuyển nó sang một PC hiện đại.


Không quan trọng là thuật toán không hiệu quả vì mục đích không thực sự là tính toán các số nguyên tố, mà là thực hiện một nhiệm vụ chung chung khó và xem nó tốt hơn hay tệ hơn so với máy tính để bàn hiện đại. Một thuật toán hiệu quả sẽ chỉ làm cho việc so sánh đó khó hơn và thậm chí có thể làm hỏng kết quả nếu nó quá tốt, nó cố tình tận dụng các tính năng / tính năng hiện đại của CPU.
Numeron

5

Lý do bạn nhận được 15% trên bộ xử lý lõi hex là vì mã của bạn sử dụng 1 lõi ở mức 100%. 100/6 = 16,67%, sử dụng đường trung bình động với lập lịch quy trình (quy trình của bạn sẽ chạy ở chế độ ưu tiên bình thường) có thể dễ dàng được báo cáo là 15%.

Do đó, để sử dụng 100% cpu, bạn sẽ cần sử dụng tất cả các lõi của CPU - khởi chạy 6 đường dẫn mã thực thi song song cho CPU lõi hex và có quy mô này phù hợp với bất kỳ bộ xử lý nào mà máy Cray của bạn có :)


Vấn đề khi làm việc này là làm thế nào tôi có thể có được một con số rõ ràng về tốc độ của từng máy? Ngoài ra Cray có "bộ xử lý vector" rõ ràng, vì vậy nó đòi hỏi công việc một tải hơn này để làm cho nó chạy đúng
túi người đàn ông

Không biết. Có thể là sự khác biệt trong các quy trình lập lịch trình.
Carl

2

Cũng cần lưu ý cách bạn đang tải CPU. Một CPU có thể thực hiện nhiều tác vụ khác nhau và trong khi nhiều tác vụ trong số chúng sẽ được thông báo là "đang tải 100% CPU", chúng có thể sử dụng 100% các bộ phận khác nhau của CPU. Nói cách khác, rất khó để so sánh hai CPU khác nhau về hiệu suất và đặc biệt là hai kiến ​​trúc CPU khác nhau. Việc thực thi tác vụ A có thể ưu tiên một CPU hơn một CPU khác, trong khi thực thi tác vụ B có thể dễ dàng ngược lại (vì hai CPU có thể có các tài nguyên bên trong khác nhau và có thể thực thi mã rất khác nhau).

Đây là lý do tại sao phần mềm cũng quan trọng để làm cho máy tính hoạt động tối ưu như phần cứng. Điều này thực sự rất đúng đối với "siêu máy tính".

Một thước đo cho hiệu suất của CPU có thể là các lệnh trên giây, nhưng sau đó một lần nữa các lệnh không được tạo bằng nhau trên các kiến ​​trúc CPU khác nhau. Một biện pháp khác có thể là hiệu suất IO của bộ nhớ cache, nhưng cơ sở hạ tầng bộ nhớ cache cũng không bằng. Sau đó, một thước đo có thể là số lượng lệnh trên mỗi watt được sử dụng, vì việc phân phối và tiêu tán điện năng thường là một yếu tố hạn chế khi thiết kế một máy tính cụm.

Vì vậy, câu hỏi đầu tiên của bạn nên là: Thông số hiệu suất nào quan trọng đối với bạn? Bạn muốn đo gì? Nếu bạn muốn xem máy nào đạt FPS nhiều nhất trong Quake 4, câu trả lời rất dễ dàng; thiết bị chơi game của bạn sẽ, vì Cray không thể chạy chương trình đó ;-)

Chúc mừng, Steen


2

TLDR; Câu trả lời được chấp nhận là không hiệu quả và không tương thích. Bí danh theo dõi hoạt động nhanh hơn 100 lần.

Không thể chạy trình biên dịch gcc trên MAC omp. Tôi đã phải cài đặt llvm (brew install llvm ). Nhưng tôi không thấy CPU không hoạt động đã giảm xuống khi chạy phiên bản OMP.

Đây là ảnh chụp màn hình khi phiên bản OMP đang chạy. nhập mô tả hình ảnh ở đây

Ngoài ra, tôi đã sử dụng luồng POSIX cơ bản, có thể chạy bằng bất kỳ trình biên dịch c nào và thấy gần như toàn bộ CPU được sử dụng hết khi nos of thread= no of cores= 4 (MacBook Pro, Intel Core i5 2,3 GHz). Đây là chương trình -

Lưu ý cách toàn bộ CPU được sử dụng hết - nhập mô tả hình ảnh ở đây

PS - Nếu bạn tăng không có luồng nào thì mức sử dụng CPU thực tế sẽ giảm xuống (Hãy thử tạo số luồng không = 20.) vì hệ thống sử dụng nhiều thời gian hơn trong chuyển đổi ngữ cảnh so với tính toán thực tế.

Nhân tiện, máy của tôi không mạnh mẽ như @mystical (Câu trả lời được chấp nhận). Nhưng phiên bản của tôi với phân luồng POSIX cơ bản hoạt động nhanh hơn phiên bản OMP. Đây là kết quả -

nhập mô tả hình ảnh ở đây

PS Tăng tải luồng lên 2,5 triệu để xem mức sử dụng CPU, vì nó hoàn thành trong vòng chưa đầy một giây.


0

Cố gắng song song hóa chương trình của bạn bằng cách sử dụng, ví dụ: OpenMP. Nó là một khung rất đơn giản và hiệu quả để tạo các chương trình song song.


0

Để cải thiện nhanh chóng một lõi, hãy xóa lệnh gọi hệ thống để giảm chuyển đổi ngữ cảnh. Xóa những dòng này:

Đầu tiên là đặc biệt tồi tệ, vì nó sẽ tạo ra một quy trình mới mỗi lần lặp lại.


0

Đơn giản chỉ cần cố gắng Zip và Giải nén một tệp lớn, không có gì vì các hoạt động I / o nặng có thể sử dụng cpu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.