Tại sao một chương trình sẽ yêu cầu số lượng lõi CPU tối thiểu cụ thể?


55

Có thể viết mã (hoặc phần mềm hoàn chỉnh, thay vì một đoạn mã) sẽ không hoạt động đúng khi chạy trên CPU có ít hơn N số lõi? Không kiểm tra nó một cách rõ ràng và thất bại về mục đích:

NẾU (noOfCores <4) THÌ không chạy đúng mục đích

Tôi đang xem xét các yêu cầu hệ thống tối thiểu của trò chơi ( Dragon Age: Inquisition ) và nó chỉ ra tối thiểu CPU bốn lõi. Nhiều người chơi nói rằng nó KHÔNG chạy trên CPU hai lõi và NGAY trên Intel Core i3 với hai lõi vật lý và hai lõi logic. Và đó KHÔNG phải là vấn đề về sức mạnh tính toán.

Theo hiểu biết của tôi, các luồng được cách ly hoàn toàn khỏi CPU bởi HĐH vì điều đó không thể thực hiện được.

Chỉ để xóa mọi thứ:

Tôi KHÔNG hỏi "Tôi có thể tìm ra số lượng lõi CPU từ mã không và có mục đích không?" ... Mã như vậy sẽ không có ý định (buộc bạn phải mua CPU đắt tiền hơn để chạy chương trình - mà không cần năng lượng tính toán). Tôi đang yêu cầu mã của bạn, có bốn luồng và không thành công khi hai luồng được chạy trên cùng một lõi vật lý (mà không kiểm tra rõ ràng thông tin hệ thống và cố tình không thành công) .

Nói tóm lại, có thể có phần mềm yêu cầu nhiều lõi, mà không cần sức mạnh tính toán bổ sung đến từ nhiều lõi không? Nó sẽ chỉ yêu cầu N lõi vật lý riêng biệt.


11
Nếu bạn đọc kỹ câu hỏi của tôi, bạn sẽ thấy họ không hỏi điều tương tự.
uylmz

21
Vì số lượng lõi có thể được truy xuất, nó có thể được so sánh với N và nếu so sánh đó đánh giá là đúng, mã có thể làm bất cứ điều gì nó muốn, bao gồm nhưng không giới hạn hành vi theo cách không được quảng cáo. Câu hỏi của bạn là gì?

3
Bạn có chắc chắn vấn đề thực sự và liên quan trực tiếp đến số lượng lõi? Có lẽ trò chơi được đề cập một phần chỉ dựa trên một tính năng (chính xác) được cung cấp bởi CPU có ít nhất 4 lõi?
mgoeminne

25
Lưu ý rằng "yêu cầu hệ thống tối thiểu" thường là "yêu cầu hệ thống tối thiểu để chạy với hiệu suất chấp nhận được", đặc biệt là với các trò chơi. Về mặt lý thuyết, Dragon Age có thể chạy trên một hộp lõi đơn, nhưng nếu bạn làm như vậy, nó sẽ hiển thị các khung hình khổng lồ. Vì vậy, họ yêu cầu số lõi này không bắt buộc bạn phải mua phần cứng, nhưng để tránh khiếu nại về chất lượng từ người dùng phần cứng cấp thấp hơn.
Gort Robot

3
@Sebb: Tôi nghĩ rằng bạn đang tham gia vào một cái gì đó: nếu 4 lõi vật lý tương quan với việc có nhiều bộ đệm hơn thì 2 logic / 4 logic, thì trò chơi có thể tự nhiên bị nghẹt trên các máy 2x2 mà không đạt giới hạn sức mạnh xử lý của chúng vì nó thiếu bộ nhớ cache thời gian. Thử nghiệm sẽ là tìm một CPU có 2x2 lõi và tải bộ đệm, hoặc 4 lõi và ít bộ đệm, và xem điều gì sẽ xảy ra.
Steve Jessop

Câu trả lời:


45

Có thể làm điều này "một cách tình cờ" với việc sử dụng mối quan hệ cốt lõi bất cẩn. Hãy xem xét các mã giả sau đây:

  • bắt đầu một chủ đề
  • trong luồng đó, tìm xem nó đang chạy trên lõi nào
  • đặt ái lực CPU của nó vào lõi đó
  • bắt đầu làm một cái gì đó tính toán chuyên sâu / vòng lặp mãi mãi

Nếu bạn khởi động bốn trong số đó trên CPU hai lõi, thì có điều gì đó không ổn với cài đặt mối quan hệ cốt lõi hoặc bạn kết thúc với hai luồng gây ra các lõi có sẵn và hai luồng không bao giờ được lên lịch. Không có gì rõ ràng nó đã hỏi tổng cộng có bao nhiêu lõi.

(Nếu bạn có các luồng chạy dài, việc đặt ái lực CPU thường cải thiện thông lượng)

Ý tưởng rằng các công ty game đang "buộc" mọi người mua phần cứng đắt tiền hơn mà không có lý do chính đáng nào là không hợp lý. Nó chỉ có thể mất khách hàng của họ.

Chỉnh sửa: bài đăng này hiện đã có 33 lượt upvote, khá nhiều cho rằng nó dựa trên phỏng đoán có giáo dục!

Dường như mọi người đã có DA: Tôi chạy, rất tệ, trên các hệ thống lõi kép: http://www.dsogaming.com/pc-performance-analyses/dragon-age-inquisition-pc-performance-analysis/ Phân tích đó đề cập rằng tình hình sẽ cải thiện đáng kể nếu siêu phân luồng được bật. Do HT không thêm bất kỳ đơn vị vấn đề hướng dẫn hoặc bộ đệm nào, nó chỉ cho phép một luồng chạy trong khi một luồng khác nằm trong gian hàng bộ đệm, điều đó cho thấy mạnh mẽ rằng nó được liên kết hoàn toàn với số lượng luồng.

Một poster khác tuyên bố rằng việc thay đổi trình điều khiển đồ họa hoạt động: http://answers.ea.com/t5/Dragon-Age-Inquisition/Working-solution-for-Intel-dual-core-CPUs/td-p/3994141 ; cho rằng trình điều khiển đồ họa có xu hướng là một tổ ong tồi tệ của cặn bã và dân làng, điều này không đáng ngạc nhiên. Một bộ trình điều khiển khét tiếng có chế độ "chính xác & chậm" so với "nhanh & không chính xác" đã được chọn nếu được gọi từ QUAKE.EXE. Các trình điều khiển hoạt động khác nhau đối với số lượng CPU rõ ràng khác nhau. Có lẽ (quay lại đầu cơ) một cơ chế đồng bộ hóa khác được sử dụng. Lạm dụng spinlocks ?

"Sử dụng sai các nguyên tắc khóa và đồng bộ hóa" là một nguồn rất phổ biến của các lỗi. (Lỗi tôi phải xem xét tại nơi làm việc trong khi viết đây là "sự cố nếu thay đổi cài đặt máy in cùng lúc khi công việc in kết thúc").

Chỉnh sửa 2: bình luận đề cập đến hệ điều hành cố gắng tránh chết đói luồng. Lưu ý rằng trò chơi có thể có bộ lập lịch nội bộ riêng để phân công công việc cho các luồng và sẽ có một cơ chế tương tự trong chính card đồ họa (đây thực sự là một hệ thống đa nhiệm). Cơ hội của một lỗi trong một trong số đó hoặc sự tương tác giữa chúng là khá cao.

www.ecsl.cs.sunysb.edu/tr/ashok.pdf (2008) là một luận án tốt nghiệp về lập lịch tốt hơn cho các card đồ họa trong đó đề cập rõ ràng rằng họ thường sử dụng lập lịch trước được phục vụ trước, dễ thực hiện trong hệ thống không phòng ngừa. Tình hình đã được cải thiện? Chắc là không.


1
Vâng, có hai phần để trả lời câu hỏi này: ái lực CPU cho phép người ta mã hóa thứ gì đó sẽ biến điều này thành yêu cầu kỹ thuật trong Windows, câu trả lời thay thế là hệ thống thời gian thực rất chắc chắn có thể yêu cầu những thứ như vậy. +1 vì là người duy nhất đề cập đến mối quan hệ CPU thực sự là thủ phạm có khả năng nhất cho những gì đang được hỏi ở đây.
Jimmy Hoffa

3
Điều gì có thể đi sai nếu bạn đặt mối quan hệ với cốt lõi hiện tại? Với đa nhiệm được ưu tiên, chuỗi chờ sẽ được lên lịch trừ khi hiện tại có mức ưu tiên tối đa có thể ("thời gian thực" trong Windows). Tôi sẽ thấy một kịch bản khác: mỗi trong số 4 luồng được gán ái lực được xác định tĩnh là 1,2,4,8, trong trường hợp đó, hai luồng sau sẽ không bao giờ được lên lịch (mặc dù tôi không chắc chắn nếu đặt mối quan hệ thành hiệu quả không là sẽ thành công).
Ruslan

@Ruslan Có thể cố gắng đặt mối quan hệ không hợp lệ sẽ làm hỏng ứng dụng ngay từ đầu?
Luaan

1
@Luaan đó không phải hoạt động rủi ro để dẫn đến sụp đổ. Tối đa những gì tôi mong đợi là một lỗi được HĐH trả về. Tôi vừa kiểm tra, trong Linux tôi gặp lỗi "Đối số không hợp lệ". Không biết Windows sẽ nói gì.
Ruslan

@Ruslan Mỗi hệ điều hành lớn trong một thập kỷ chắc chắn đã bao gồm mã để tránh chết đói luồng (thường bằng cách tăng mức độ ưu tiên của luồng sau khi nó không chạy đủ lâu).
Voo

34

Có thể cần phải có 4 lõi vì ứng dụng chạy bốn tác vụ theo các luồng song song và hy vọng chúng sẽ hoàn thành gần như đồng thời.

Khi mỗi luồng được thực thi bởi một lõi riêng biệt và tất cả các luồng có cùng khối lượng công việc tính toán chính xác, chúng hoàn toàn có khả năng (nhưng không được đảm bảo) để hoàn thành gần như cùng một lúc. Nhưng khi hai luồng chạy trên một lõi, thời gian sẽ ít dự đoán hơn vì lõi sẽ chuyển ngữ cảnh giữa hai luồng mọi lúc.

Lỗi xảy ra do thời gian xử lý luồng không mong muốn được gọi là " điều kiện cuộc đua ".

Trong bối cảnh phát triển trò chơi, một kiến ​​trúc hợp lý với loại vấn đề này có thể là một trong đó các tính năng khác nhau của trò chơi được mô phỏng theo thời gian thực bởi các luồng CPU khác nhau. Khi mỗi tính năng chạy trên một lõi riêng, tất cả chúng đều được mô phỏng với tốc độ gần như nhau. Nhưng khi hai tính năng chạy trên một lõi, cả hai sẽ chỉ được mô phỏng nhanh bằng một nửa so với phần còn lại của thế giới trò chơi, có thể gây ra tất cả các loại hành vi kỳ lạ.

Lưu ý rằng một kiến ​​trúc phần mềm phụ thuộc vào các luồng độc lập chạy với thời gian cụ thể là cực kỳ mong manh và là dấu hiệu của sự hiểu biết rất xấu về lập trình đồng thời. Trên thực tế, có tất cả các tính năng có sẵn trong tất cả các API đa luồng để đồng bộ hóa các luồng một cách rõ ràng để ngăn chặn các loại vấn đề này.


11
Nhưng bất kỳ trò chơi nào cũng có sự phụ thuộc mong manh vào việc có thể hoàn thành tất cả các tính toán cho khung hình tiếp theo để kịp thời kết xuất nó với tần suất hợp lý. Ngay cả khi 4 luồng của bạn được đồng bộ hóa chính xác, có thể không thể hiển thị kịp thời và không có lợi ích trong trò chơi có thể tính toán chính xác nhưng không thể phát được do bị lag và nói lắp.
Vô dụng

1
@ Vô dụng: Điều đó không thực sự đúng. Ví dụ, bạn có thể tạo khung đệm hoặc dữ liệu mô phỏng để ẩn bất kỳ lỗi nào và có các thiết kế đồng thời phù hợp hơn. Làm cho tất cả quá trình xử lý của bạn được thực hiện trong thời gian X và yêu cầu đồng bộ hóa chính xác quá trình xử lý đó là những vấn đề khác nhau.
DeadMG

23
"Một kiến ​​trúc phần mềm phụ thuộc vào các luồng độc lập chạy với thời gian cụ thể là cực kỳ mong manh" Đó chính xác là lý do tại sao tôi không thể tưởng tượng một trò chơi không chạy hoàn toàn với 2 lõi, nhưng hoạt động đáng tin cậy với 4 lõi. Ngay cả với 4 lõi, thời gian sẽ không thể đoán trước, do đó, điều kiện cuộc đua cũng sẽ xảy ra, ngay cả khi ít thường xuyên hơn.
Svick

8
@svick tất nhiên rồi. Nhưng câu hỏi đặt ra là "có thể không?" không phải là "nó lành mạnh?"
dùng253751

5
Bất kỳ mã nào có loại "điều kiện chủng tộc" này đều bị hỏng , bất kể bạn chạy bao nhiêu lõi. (Đặc biệt là vì hoàn toàn không có gì đảm bảo về những gì khác đang chạy trên hệ thống.) Tôi thực sự nghi ngờ đây là nguyên nhân, do nó sẽ dễ dàng di chuyển trò chơi ngay cả trên hệ thống hexacore ...
DevSolar

16

Không chắc là những "yêu cầu tối thiểu" này đại diện cho thứ gì đó bên dưới mà trò chơi sẽ không chạy. Nhiều khả năng là chúng đại diện cho thứ gì đó bên dưới mà trò chơi sẽ không chạy với hiệu suất chấp nhận được. Không có công ty trò chơi nào muốn đối phó với nhiều khách hàng phàn nàn về hiệu suất khủng khiếp khi họ đang chạy nó trên hộp 1 Ghz lõi đơn, ngay cả khi phần mềm có thể chạy kỹ thuật. Vì vậy, họ có thể cố tình thiết kế để thất bại cứng trên các hộp có ít lõi hơn sẽ mang lại cho họ hiệu suất chấp nhận được.

Một số liệu quan trọng trong hiệu suất trò chơi là tốc độ khung hình. Thông thường họ chạy ở tốc độ 30 hoặc 60 khung hình mỗi giây. Điều này có nghĩa là công cụ trò chơi phải hiển thị chế độ xem hiện tại từ trạng thái trò chơi trong một khoảng thời gian cố định. Để đạt được 60 khung hình / giây, chỉ cần hơn 16 ms để thực hiện điều này. Các trò chơi có đồ họa cao cấp bị ràng buộc rất nhiều về CPU và do đó, có một sự cho và nhận lớn giữa việc cố gắng đẩy chất lượng cao hơn (cần nhiều thời gian hơn) và cần phải duy trì ngân sách thời gian này. Vì vậy, ngân sách thời gian cho mỗi khung hình là vô cùng chặt chẽ.

Vì ngân sách thời gian eo hẹp, nhà phát triển lý tưởng muốn truy cập độc quyền vào một hoặc nhiều lõi. Họ cũng có khả năng muốn có thể thực hiện công cụ kết xuất của mình trong lõi, vì đó là những gì phải hoàn thành trong ngân sách thời gian đó, trong khi những thứ khác, như tính toán trạng thái thế giới, xảy ra trên một quy trình riêng biệt, nơi nó sẽ không xâm nhập.

Về lý thuyết, bạn có thể nhồi nhét tất cả những thứ này vào một lõi, nhưng sau đó mọi thứ trở nên khó khăn hơn nhiều. Đột nhiên bạn phải đảm bảo tất cả những thứ trạng thái trò chơi đó xảy ra đủ nhanh và cho phép kết xuất của bạn xảy ra. Bạn không thể biến chúng thành hai luồng phần mềm vì không có cách nào để HĐH hiểu "luồng A phải hoàn thành khối lượng công việc X trong 16 ms bất kể luồng B làm gì".

Các nhà phát triển trò chơi không quan tâm đến việc khiến bạn mua phần cứng mới. Lý do họ có yêu cầu hệ thống là chi phí hỗ trợ các máy cấp thấp hơn không đáng.


Mặc dù điều này là đúng, nhưng điều đó xảy ra là bạn có thể mua phần cứng lõi kép đủ mạnh để có thể đạt được nhiều hơn trong một khung thời gian nhất định so với phần cứng lõi tứ được mô tả trong thông số kỹ thuật tối thiểu. Tại sao nhà cung cấp không liệt kê phần cứng như vậy có thể chấp nhận được, một quyết định chỉ có thể làm mất doanh số của họ?
Jules

4
Điều cần so sánh không phải là 2 so với 4 lõi. Về cơ bản, đó là 1 so với 3 lõi, vì CPU # 0 sẽ bị ràng buộc khá nhiều bởi trình điều khiển đồ họa và DPC. Ngoài ra còn có các hiệu ứng di chuyển và bộ đệm đáng kể nếu bạn đăng ký CPU với một số loại tác vụ trong hệ thống công việc của một trò chơi hiện đại điển hình. Yêu cầu là có bởi vì Frostbite (động cơ của DA: I) được thiết kế từ đầu với điều chỉnh rất cẩn thận đòi hỏi một số lõi cụ thể.
Lars Viklund

6
@LarsViklund Có vẻ như bạn biết nhiều chi tiết hơn bất kỳ ai khác ở đây. Bạn đã cân nhắc việc đặt câu trả lời cùng nhau chưa?
Gort Robot

1
"Không chắc là những" yêu cầu tối thiểu "này đại diện cho thứ gì đó bên dưới mà trò chơi sẽ không chạy. Nhiều khả năng là chúng đại diện cho thứ gì đó bên dưới mà trò chơi sẽ không chạy với hiệu suất chấp nhận được." - G3258 của Intel là bộ xử lý lõi kép rất mạnh được các game thủ sử dụng rộng rãi, có khả năng chạy các trò chơi bằng hoặc nhiều tài nguyên hơn so với Dragon Age Inquisition, nhưng nhiều người chơi cho biết trò chơi không chạy trên đó.
uylmz

2
@Reek Tôi nghi ngờ rằng người dùng cuối có thể dễ dàng biết mức độ thâm dụng tài nguyên của một trò chơi cụ thể so với trò chơi khác.
Gort Robot

9

Ba chủ đề thời gian thực không bao giờ ngủ và một chủ đề khác. Nếu có ít hơn bốn lõi, luồng thứ tư không bao giờ chạy. Nếu luồng thứ tư cần giao tiếp với một trong các luồng thời gian thực để luồng thời gian thực kết thúc, mã sẽ không kết thúc với ít hơn bốn lõi.

Rõ ràng nếu các chủ đề thời gian thực đang chờ đợi một cái gì đó không cho phép chúng ngủ (chẳng hạn như một spinlock), nhà thiết kế chương trình đã làm hỏng.


1
Có thể cho rằng, khi một ứng dụng người dùng yêu cầu các luồng thời gian thực ở vị trí đầu tiên, nhà thiết kế đã bắt đầu: D
Luaan

2
Tôi đã làm xong. Nửa triệu dòng mã. Một trường hợp sử dụng khoảng 300 dòng. Chuỗi thời gian thực dành phần lớn thời gian chờ đợi đầu vào để nó có thể đánh dấu thời gian đầu vào và đưa nó đến một chuỗi ưu tiên thấp hơn.
Joshua

2
@Luaan Đối với hầu hết các ứng dụng tôi đồng ý với bạn, nhưng các trò chơi là một quái thú khác, cũng như các ứng dụng nhúng. Trong cả hai trường hợp đó, mối quan tâm để chơi đẹp với các ứng dụng đồng thời khác chủ yếu xuất hiện ngoài cửa sổ có lợi cho hiệu suất.
thiệu lại vào

Mặc dù nó sẽ không đặc biệt hiệu quả, nhưng kịch bản này sẽ không dẫn đến bất kỳ sự bế tắc nào - đảo ngược ưu tiên sẽ quan tâm đến nó (giả sử bất kỳ lịch trình nửa chừng nào trong bất kỳ HĐH chính nào của thập kỷ trước)
Voo

2
@Joshua > Windows không biết đảo ngược ưu tiên là gì. Gì? support.microsoft.com/kb/96418 , msdn.microsoft.com/en-us/l Library / windows / desktop / ms684831.aspx . Ngoài ra, đảo ngược ưu tiên là thuật ngữ mô tả vấn đề , không phải là giải pháp (@Voo).
Bob

3

Trước hết, các luồng phần mềm không liên quan gì đến các luồng phần cứng và thường bị lẫn lộn. Các luồng phần mềm là các đoạn mã hơn có thể được gửi và tự chạy trong bối cảnh quy trình. Các luồng phần cứng hầu hết được quản lý bởi HĐH và được gửi đến lõi của bộ xử lý khi nói về các chương trình thông thường. Các luồng phần cứng này được gửi dựa trên tải; bộ điều phối luồng phần cứng hoạt động ít nhiều giống như một bộ cân bằng tải.

Tuy nhiên, khi nói đến chơi game, đặc biệt là chơi game cao cấp, đôi khi các luồng phần cứng được quản lý bởi chính trò chơi hoặc trò chơi hướng dẫn người điều phối luồng phần cứng phải làm gì. Đó là bởi vì mọi nhiệm vụ hoặc nhóm nhiệm vụ không có cùng mức độ ưu tiên như trong một chương trình bình thường. Bởi vì tuổi rồng đến từ một studio trò chơi cao cấp sử dụng các công cụ trò chơi cao cấp, tôi có thể tưởng tượng rằng nó sử dụng công văn "thủ công" và sau đó số lượng lõi trở thành một yêu cầu hệ thống tối thiểu. Bất kỳ chương trình nào cũng gặp sự cố khi tôi gửi một đoạn mã đến lõi vật lý thứ 3 chạy trên máy chỉ có 1 hoặc 2 lõi.


Điều này. Hãy nhớ rằng nói "kiểm tra không có lõi" có nghĩa là một công ty đang sản xuất sản phẩm phần mềm của mình theo một cách cụ thể để buộc người dùng mua phần cứng đắt tiền hơn (điều này sẽ không có mục đích).
uylmz

2
Những vấn đề này tồn tại miễn là có chơi game trên PC. Lúc đầu, chúng tôi có 486dx và 486sx, sau đó là MMX và không phải MMX Pentium, lõi và không lõi và ngày nay chúng tôi có các yêu cầu n-core. Đây là một trong những lý do tại sao bàn giao tiếp vẫn tồn tại.
dj bazzie wazzie 7/1/2015

4
Bạn có tài liệu tham khảo cho các trò chơi tiếp quản lịch trình CPU không? Theo như tôi biết, điều này không thể trực tiếp trong Windows, ít nhất là không theo cách mà bạn sẽ thất bại theo cách bạn đề xuất.
Jules

2
@djbazziewazzie thực sự các cửa sổ cung cấp một api để làm việc đó, tôi đã thiết lập một chủ đề để luôn sử dụng cùng một lõi; đây được gọi là mối quan hệ luồng và không cho phép bạn chọn thủ công đoạn mã nào chạy ở đâu và khi nào và không thể gây ra lỗi hệ thống như bạn đề xuất (hệ thống sẽ bỏ qua yêu cầu đặt mối quan hệ với lõi không tồn tại và chỉ cần lập lịch trình luồng cho bất kỳ lõi nào khi nó khả dụng. Tôi khá chắc chắn đây là thứ mà id Tech sử dụng và nó không thực sự có giá trị để "tự quản lý các luồng phần cứng".
Jules

1
@djbazziewazzie Bạn cũng có vẻ hiểu sai quan điểm của Grand Central Dispatch, điều này không cho phép các nhà phát triển kiểm soát nhiều hơn về cách mã của họ được lên lịch vào lõi; trong thực tế, mục đích của nó hoàn toàn ngược lại: lựa chọn số lượng luồng cần tạo và mã nào sẽ chạy trên luồng nào trong tay các ứng dụng để có thể tối ưu hóa cho phần cứng có sẵn ở cấp độ toàn hệ thống. Sự phụ thuộc vào việc có một số lõi nhất định chính xác là loại vấn đề GCD được thiết kế để ngăn chặn.
Jules

1

Vì có thể sử dụng ảo hóa để có nhiều lõi ảo hơn vật lý và phần mềm sẽ không biết nó đang chạy trên ảo hóa và thay vào đó nghĩ rằng nó có nhiều lõi vật lý, tôi sẽ nói rằng phần mềm như vậy là không thể.

Điều đó có nghĩa là, không thể viết phần mềm sẽ luôn dừng trên ít hơn N lõi.

Như những người khác đã chỉ ra, có những giải pháp phần mềm có khả năng kiểm tra, đặc biệt là nếu hệ điều hành và mã được sử dụng có ít sự bảo vệ chống lại các điều kiện chủng tộc khi các quá trình N chạy trên bộ xử lý <N. Thủ thuật thực sự là mã sẽ thất bại khi bạn có ít hơn bộ xử lý N nhưng sẽ không thất bại khi bạn có bộ xử lý N nhưng có một hệ điều hành có thể gán công việc cho ít hơn bộ xử lý N.


1

Có thể có ba luồng làm một cái gì đó (tạo nền hoặc tạo chuyển động NPC) và chuyển các sự kiện sang một thứ tư, được cho là tổng hợp / lọc các sự kiện và cập nhật mô hình xem. Nếu luồng thứ tư không nhận được tất cả các sự kiện (vì nó không được lên lịch trên lõi) thì mô hình khung nhìn sẽ không được cập nhật chính xác. Điều này chỉ có thể xảy ra lẻ tẻ, nhưng những lõi đó cần phải có sẵn tại bất kỳ thời điểm nào. Điều này có thể giải thích tại sao bạn không thấy sử dụng CPU cao mọi lúc, nhưng dù sao thì trò chơi vẫn không hoạt động bình thường.


1
Trong một kịch bản như vậy, trò chơi cũng sẽ thất bại ngẫu nhiên khi các dịch vụ nền được lên lịch để chạy, điều này khá thường xuyên trên hầu hết các chiếc.
Jules

1

Tôi nghĩ Joshua đang đi đúng hướng, chỉ là chưa đi đến kết luận.

Giả sử bạn có một kiến ​​trúc trong đó có ba luồng được viết để làm nhiều nhất có thể - khi họ hoàn thành những gì họ đang làm, họ sẽ làm lại. Để duy trì hiệu suất, các luồng này không giải phóng quyền kiểm soát cho bất cứ điều gì - chúng không muốn mạo hiểm độ trễ từ bộ lập lịch tác vụ Windows. Chừng nào có 4 lõi trở lên thì nó hoạt động tốt, nó sẽ thất bại nặng nề nếu không có.

Nói chung đây sẽ là lập trình tồi nhưng game lại là vấn đề khác - khi bạn phải đối mặt với sự lựa chọn giữa một thiết kế kém hơn tất cả phần cứng hoặc thiết kế vượt trội về phần cứng đủ tốt hoặc thất bại đối với các nhà phát triển trò chơi phần cứng kém hơn thường chọn để yêu cầu phần cứng.


Thông thường không thể viết một luồng sẽ không từ bỏ quyền kiểm soát đối với các luồng khác. Tất cả các hệ điều hành không RTOS hiện đại đều sử dụng đa nhiệm được ưu tiên, điều này cố ý làm cho luồng (chế độ người dùng) không thể giải phóng quyền kiểm soát của một lõi nhất định. Chủ đề hạt nhân, tất nhiên, là một vấn đề khác nhau.
thiệu lại vào

@reirab Tăng ưu tiên của nó.
Loren Pechtel

@Loren Không thay đổi thực tế rằng trình lập lịch biểu vẫn hoạt động, nghĩa là bạn phải chia sẻ thời gian với các luồng khác có cùng mức độ ưu tiên và trình lập lịch ưu tiên tăng cường các luồng bị bỏ đói. Bạn không thể làm điều đó trên các hệ điều hành bình thường và thậm chí nếu bạn có thể, các trò chơi chắc chắn sẽ không phải là một ứng dụng chấp nhận được khi làm như vậy.
Voo

1

Is it possible to write code (or complete software, rather than a piece of code) that won't work properly when run on a CPU that has less than N number of cores?

Chắc chắn rồi. Việc sử dụng các luồng thời gian thực sẽ là một ví dụ điển hình cho tình huống này, không chỉ có thể, mà là cách mong muốn (và thường là cách duy nhất đúng) để hoàn thành công việc. Tuy nhiên, các luồng thời gian thực thường được giới hạn trong nhân hệ điều hành, thường là cho các trình điều khiển cần có khả năng đảm bảo rằng một sự kiện phần cứng nào đó được xử lý trong một khoảng thời gian xác định. Bạn không nên có các luồng thời gian thực trong các ứng dụng người dùng thông thường và tôi không chắc chắn rằng thậm chí có thể có một luồng trong ứng dụng chế độ người dùng Windows. Nói chung, các hệ điều hành làm cho nó không thể thực hiện điều này một cách chính xác từ đất của người dùng vì nó cho phép một ứng dụng nhất định chiếm quyền kiểm soát hệ thống.

Về các ứng dụng đất người dùng: Giả định của bạn rằng việc kiểm tra một số luồng nhất định để chạy là nhất thiết có hại trong ý định là không chính xác. Chẳng hạn, bạn có thể có 2 nhiệm vụ chuyên sâu, hiệu năng dài cần có cốt lõi cho chính mình. Bất kể tốc độ lõi CPU, chia sẻ lõi với các luồng khác có thể là sự suy giảm hiệu năng nghiêm trọng và không thể chấp nhận được do lỗi bộ nhớ cache cùng với các hình phạt thông thường phát sinh khi chuyển đổi luồng (khá đáng kể.) Trong trường hợp này, nó sẽ hoàn toàn hợp lý, đặc biệt đối với một trò chơi, để đặt mỗi luồng này chỉ có ái lực trên một lõi cụ thể cho từng luồng và sau đó đặt tất cả các luồng khác của bạn không có ái lực trên 2 lõi đó. Tuy nhiên, để làm điều này, bạn '


1

Bất kỳ mã nào sử dụng spinlocks với bất kỳ sự tranh chấp khóa đáng chú ý nào cũng sẽ hoạt động khủng khiếp (đến một mức độ - đối với một ứng dụng như trò chơi - bạn có thể nói "không hoạt động" ) nếu số lượng luồng vượt quá số lượng lõi.

Ví dụ, hãy tưởng tượng một luồng sản xuất gửi các tác vụ đến một hàng đợi phục vụ 4 luồng tiêu dùng. Chỉ có hai lõi:

Nhà sản xuất cố gắng để có được spinlock, nhưng nó được giữ bởi một người tiêu dùng chạy trên lõi khác. Hai lõi đang chạy khóa trong khi nhà sản xuất đang quay, chờ khóa được phát hành. Điều này đã là xấu, nhưng không tệ như nó sẽ nhận được.
Thật không may, luồng tiêu dùng ở cuối lượng tử thời gian của nó, vì vậy nó bị cấm và một luồng tiêu dùng khác được lên lịch. Nó cố gắng giữ khóa, nhưng dĩ nhiên là khóa được lấy, vì vậy bây giờ hai lõi đang quay và chờ đợi điều gì đó không thể xảy ra.
Chuỗi sản xuất đến hết lát cắt thời gian của nó và được ưu tiên, một người tiêu dùng khác thức dậy. Một lần nữa, hai người tiêu dùng đang chờ khóa được phát hành và điều đó sẽ không xảy ra trước khi hai lượng tử thời gian nữa trôi qua.
[...] Cuối cùng, người tiêu dùng đang giữ spinlock đã phát hành khóa. Nó ngay lập tức được thực hiện bởi bất cứ ai đang quay trên lõi khác. Có 75% cơ hội (3 đến 1) rằng đó là một chủ đề tiêu dùng khác. Nói cách khác, 75% khả năng nhà sản xuất vẫn đang bị đình trệ. Tất nhiên điều này có nghĩa là người tiêu dùng cũng bị đình trệ. Không có nhà sản xuất làm nhiệm vụ, họ không có gì để làm.

Lưu ý rằng điều này hoạt động trên nguyên tắc với bất kỳ loại khóa nào, không chỉ là spinlocks - mà hiệu ứng tàn phá nổi bật hơn nhiều với spinlocks vì CPU tiếp tục ghi chu kỳ trong khi nó không đạt được gì.

Bây giờ hãy tưởng tượng rằng ngoài các lập trình viên ở trên, một số lập trình viên đã có ý tưởng tuyệt vời để sử dụng một luồng chuyên dụng với mối quan hệ được đặt thành lõi đầu tiên, vì vậy RDTSC sẽ cho kết quả đáng tin cậy trên tất cả các bộ xử lý (dù sao thì cũng không, nhưng một số người nghĩ vậy).


Đó là lý do tại sao các spinlocks tốt hạ cấp xuống các loại khóa khác sau một thời gian nhỏ, và thậm chí những loại tốt hơn làm rất nhanh nếu các cách sử dụng của cùng một khóa đã phải hạ cấp.
Ian

-1

Nếu tôi hiểu những gì bạn đang hỏi, điều đó là có thể, nhưng đó là một điều rất, rất tồi tệ.

Ví dụ kinh điển về những gì bạn mô tả sẽ duy trì một bộ đếm được tăng lên bởi nhiều luồng. Điều này đòi hỏi hầu như không có gì trong sức mạnh tính toán nhưng đòi hỏi sự phối hợp cẩn thận giữa các luồng. Miễn là chỉ có một luồng tại một thời điểm tăng (mà thực sự là một lần đọc tiếp theo là một bổ sung theo sau là ghi), giá trị của nó sẽ luôn luôn chính xác. Điều này là do một luồng sẽ luôn đọc giá trị "trước" chính xác, thêm một luồng và viết giá trị "tiếp theo" chính xác. Nhận hai luồng vào hành động cùng một lúc và cả hai sẽ đọc cùng một giá trị "trước đó", nhận cùng một kết quả từ mức tăng và viết cùng một giá trị "tiếp theo". Bộ đếm thực sự sẽ được tăng lên chỉ một lần mặc dù hai luồng nghĩ rằng mỗi luồng đã làm điều đó.

Sự phụ thuộc giữa thời gian và tính chính xác là điều mà khoa học máy tính gọi là điều kiện chủng tộc .

Điều kiện cuộc đua thường được tránh bằng cách sử dụng các cơ chế đồng bộ hóa để đảm bảo các luồng muốn hoạt động trên một phần dữ liệu được chia sẻ phải được xếp hàng để truy cập. Bộ đếm được mô tả ở trên có thể sử dụng khóa đọc ghi cho việc này.

Không có quyền truy cập vào thiết kế nội bộ của Dragon Age: Inquisition , tất cả mọi người có thể làm là suy đoán về lý do tại sao nó hành xử theo cách của nó. Nhưng tôi sẽ đi dựa trên một số điều tôi đã thấy được thực hiện theo kinh nghiệm của riêng mình:

Có thể là chương trình dựa trên bốn luồng đã được điều chỉnh để mọi thứ hoạt động khi các luồng chạy hầu như không bị gián đoạn trên các lõi vật lý của chính chúng. Việc "điều chỉnh" có thể đến dưới dạng sắp xếp lại mã hoặc chèn giấc ngủ vào các vị trí chiến lược để giảm thiểu các lỗi do tình trạng chủng tộc gây ra trong quá trình phát triển. Một lần nữa, đây chỉ là phỏng đoán, nhưng tôi đã thấy các điều kiện cuộc đua "được giải quyết" theo cách đó nhiều lần hơn tôi quan tâm.

Chạy một chương trình như vậy trên bất kỳ thứ gì có khả năng thấp hơn môi trường mà nó được điều chỉnh sẽ đưa ra các thay đổi về thời gian là kết quả của mã không chạy nhanh hoặc nhiều khả năng là chuyển đổi ngữ cảnh. Các chuyển đổi bối cảnh xảy ra trong vật lý (nghĩa là các lõi vật lý của CPU đang chuyển đổi giữa công việc mà các lõi logic của nó đang giữ) và logic (nghĩa là HĐH trên CPU đang phân công công việc cho các lõi), nhưng hoặc là một sự khác biệt đáng kể so với những gì sẽ là thời gian thực hiện "dự kiến". Điều đó có thể mang lại hành vi xấu.

Nếu Dragon Age: Inquisition không thực hiện bước đơn giản để đảm bảo có đủ lõi vật lý có sẵn trước khi tiếp tục, đó là lỗi của EA. Có lẽ họ dành một số tiền nhỏ để bảo vệ các cuộc gọi hỗ trợ và email từ những người đã cố gắng chạy trò chơi trên quá ít phần cứng.


1
Một số người chơi nói rằng nguyên nhân của nó là do DRM chạy trên 2 lõi và trò chơi thực tế cũng chạy trên 2. Khi DRM và các luồng trò chơi chạy trên cùng một lõi, nó sẽ bị rối. Nhưng điều này nghe có vẻ không đúng với tôi, nó có thể là một câu chuyện nhỏ được tạo ra bởi một người chơi không biết nhiều về kiến ​​trúc sw hoặc hw.
uylmz 7/1/2015

4
điều kiện cuộc đua thực sự không liên quan nhiều đến số lượng lõi, -1 ... một máy lõi đơn có nhiều luồng ảo có thể có điều kiện cuộc đua hoàn toàn phụ thuộc vào kỹ thuật cắt thời gian của thời gian chạy hoặc hệ thống nhiều lõi có thể tránh được tất cả các điều kiện cuộc đua phụ thuộc về mức độ nghiêm ngặt của nó với các hoạt động của thanh ghi nhớ ...
Jimmy Hoffa

1
@Reek: Không có kiến ​​thức sâu sắc về cách thức hoạt động của chương trình, mọi thứ đều là phỏng đoán. Hai lõi để làm chỉ DRM có vẻ hơi quá đối với tôi.
Blrfl

1
@JimmyHoffa: Tôi không đồng ý. Một điều kiện cuộc đua vẫn là một điều kiện cuộc đua ngay cả khi nó không gây ra hành vi không mong muốn. Số lượng cốt lõi có thể ảnh hưởng đến việc hành vi đó có xảy ra hay không, đó là những gì người hỏi đã hỏi, nhưng tôi đã không trích dẫn nó như là biến số duy nhất.
Blrfl

-1

Windows có chức năng tích hợp sẵn cho việc này: chức năng GetLogicalProcessorIn information nằm trong API Windows . Bạn có thể gọi nó từ chương trình của bạn để lấy thông tin về lõi, lõi ảo và siêu phân luồng.

Vì vậy, câu trả lời cho câu hỏi của bạn sẽ là: Có.


3
Tôi không hỏi "Tôi có thể tìm ra không có lõi từ mã không?" ... Một mã như vậy sẽ không có mục đích (buộc bạn phải mua CPU đắt tiền hơn để chạy chương trình - mà không cần năng lượng tính toán).
uylmz

3
Hàm này cung cấp nhiều thông tin hơn sau đó chỉ là một "số lõi" thô. Với thông tin này, bạn có thể khấu trừ lõi vật lý, lõi logic và hơn thế nữa. Nếu bạn có thể khấu trừ điều đó, thì bạn có thể viết phần mềm để sử dụng thông tin này. Theo cách tốt hay xấu (chương trình sự cố khi bạn nhìn thấy 4 lõi nhưng ít hơn 4 lõi).
Pieter B

1
Điều này có thể hoạt động trong Windows, nhưng còn OSX / Linux / iOS / Android / v.v. thì sao? Mặc dù nó đang đề cập đến một trò chơi như một ví dụ nơi hành vi này được nhìn thấy (và mối tương quan tự nhiên sẽ là Windows = Gaming), nhưng dường như đó không phải là một yêu cầu cụ thể của trò chơi.
Robert

Đối với một trò chơi như Dragon Age, các hệ thống được đề cập là Windows / XBox / PS4.
Gort Robot

Linux có /proc/cpuinfosysconf(_SC_NPROCESSORS_ONLN)(cái sau được đề cập trong POSIX). Mặc dù vậy, sử dụng thông tin để thực thi ngưỡng hiệu suất tối thiểu vẫn là một hình thức khá tệ.
cHao
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.