Với một hệ thống máy tính cụ thể, có thể ước tính thời gian chạy chính xác thực tế của một đoạn mã hội


23

đây là một đoạn mã hội

section .text
    global _start       ;must be declared for using gcc
_start:                     ;tell linker entry point
    mov edx, len    ;message length
    mov ecx, msg    ;message to write
    mov ebx, 1      ;file descriptor (stdout)
    mov eax, 4      ;system call number (sys_write)
    int 0x80        ;call kernel
    mov eax, 1      ;system call number (sys_exit)
    int 0x80        ;call kernel

section .data

msg db  'Hello, world!',0xa ;our dear string
len equ $ - msg         ;length of our dear string

Với một hệ thống máy tính cụ thể, có thể dự đoán chính xác thời gian chạy thực tế của một đoạn mã hội.


30
"Chạy mã trên máy tính đó và sử dụng đồng hồ bấm giờ" có phải là câu trả lời hợp lệ không?
Draconis

4
Tôi nghi ngờ phần lớn thời gian dành cho việc thực thi đoạn mã này đang chờ I / O. Thời gian thực hiện các hướng dẫn riêng lẻ có thể dự đoán được phần nào nếu bạn biết vị trí bộ nhớ của mã và tất cả các chi tiết về bộ xử lý (hiện tại cực kỳ phức tạp), nhưng tốc độ cũng bị ảnh hưởng bởi bộ nhớ và ổ đĩa nên bạn ' d phải biết một số lượng rất lớn các chi tiết về họ là tốt. Vì vậy, trừ khi bạn xem xét các hiện tượng vật lý (cũng ảnh hưởng đến thời gian), bạn có thể nói nó có thể dự đoán được, nhưng khó có thể tưởng tượng được để làm điều đó.
IllidanS4 muốn Monica trở lại vào

4
luôn luôn có thể ước tính ...
sudo rm -rf chém

3
Đây không phải là không thể do vấn đề tạm dừng? Chúng tôi có thể chứng minh cho một số mã xem nó có dừng hay không, nhưng chúng tôi không thể có thuật toán xác định mã này cho tất cả các mã có thể.
kutschkem

2
@Falco Đó sẽ là một tài sản của hệ thống nhất định. Một số triển khai C tự do không có hệ điều hành; tất cả những gì đang chạy là một vòng lặp chính (hoặc thậm chí không phải là một vòng lặp ;-)) có thể hoặc không thể đọc từ các địa chỉ phần cứng cho đầu vào.
Peter - Tái lập Monica

Câu trả lời:


47

Tôi chỉ có thể trích dẫn từ hướng dẫn sử dụng CPU khá nguyên thủy, bộ xử lý 68020 từ khoảng năm 1986: "Tính toán thời gian chạy chính xác của chuỗi hướng dẫn là khó khăn, ngay cả khi bạn có kiến ​​thức chính xác về việc thực hiện bộ xử lý". Mà chúng ta không có. Và so với một bộ xử lý hiện đại, CPU đó là nguyên thủy .

Tôi không thể dự đoán thời gian chạy của mã đó và bạn cũng không thể. Nhưng bạn thậm chí không thể định nghĩa "thời gian chạy" của một đoạn mã là gì, khi bộ xử lý có bộ nhớ cache lớn và khả năng không theo thứ tự lớn. Một bộ xử lý hiện đại điển hình có thể có 200 lệnh "trong chuyến bay", đó là trong các giai đoạn thực hiện khác nhau. Vì vậy, thời gian từ khi cố gắng đọc byte lệnh đầu tiên, đến khi rút lại lệnh cuối cùng, có thể khá dài. Nhưng độ trễ thực tế cho tất cả các công việc khác mà bộ xử lý cần thực hiện có thể là (và thường là) ít hơn rất nhiều.

Tất nhiên thực hiện hai cuộc gọi đến hệ điều hành làm cho điều này hoàn toàn không thể đoán trước. Bạn không biết "viết vào thiết bị xuất chuẩn" thực sự làm gì, vì vậy bạn không thể dự đoán thời gian.

Và bạn không thể biết tốc độ xung nhịp của máy tính tại thời điểm chính xác bạn chạy mã. Nó có thể ở một số chế độ tiết kiệm năng lượng, máy tính có thể đã giảm tốc độ xung nhịp vì nó bị nóng, do đó, ngay cả cùng một số chu kỳ đồng hồ có thể mất nhiều thời gian khác nhau.

Tất cả trong tất cả: Hoàn toàn không thể đoán trước.


11
Tôi nghĩ rằng kết luận của bạn quá mạnh mẽ. Độ trễ và thông lượng là số liệu phổ biến để đo "thời gian chạy" của chương trình. Ngoài ra, bạn có thể chỉ cần giải quyết một định nghĩa phù hợp về "thời gian chạy". Hơn nữa, nếu bạn có một ảnh chụp nhanh về trạng thái hệ thống, hw và sw và một kiến ​​thức hoàn hảo về các phần bên trong CPU, bạn có thể dự đoán thời gian chạy. Tại Intel, họ có thể ước tính thời gian chạy, ngay cả ở đây trên SO, chúng ta có thể dự đoán độ trễ và thông số với độ chính xác theo chu kỳ. Trong trường hợp này, bên cạnh các tòa nhà chọc trời, nó thậm chí không khó lắm.
Margaret Bloom

9
@MargaretBloom thậm chí không. Tôi đặt điện thoại của mình quá gần lò, CPU ép xung để quản lý nhiệt độ, ước tính thời gian chạy của bạn đột nhiên quá thấp. Và ngay cả khi bạn tính theo chu kỳ và không thực hiện các tòa nhà, các luồng và CPU khác có thể chơi tốt với nội dung RAM hoặc chúng có thể đổ bộ nhớ của bạn vào ổ cứng trong khi bạn bị tráo đổi, dựa trên các tình huống không thể đoán trước, từ nguồn điện tăng tốc độ làm chậm ổ cứng vừa đủ để một luồng cạnh tranh có đủ bộ nhớ kịp thời để phá hỏng ổ đĩa của bạn, tất cả các cách để xâu thẳng xúc xắc để xem có bao nhiêu thời gian để lãng phí.
John Dvorak

6
Bên cạnh đó, "kiến thức đầy đủ về trạng thái hệ thống, hw và sw" là một thứ tự khá cao, methinks. Thêm "10 ms trước" và bạn đã yêu cầu điều không thể. Và nếu việc triển khai tạo số ngẫu nhiên phần cứng của CPU của bạn sử dụng hiện tượng lượng tử (có thể xảy ra) và một số luồng trên CPU gọi nó, thì thậm chí không biết trạng thái hoàn chỉnh của vũ trụ 3000 km quanh máy tính sẽ giúp bạn tiết kiệm. Và trong MWI, bạn thậm chí không thể đoán đúng.
John Dvorak

8
@Nat: Ngay cả trong mật mã học, "thời gian không đổi" thực sự không có nghĩa là hoàn toàn không đổi - điều đó chỉ có nghĩa là thời gian chạy không có các biến thể hệ thống phụ thuộc vào dữ liệu bí mật và có thể tương quan thống kê với nó. Và trong thực tế, người ta thường chỉ giả định rằng nếu đường dẫn mã được thực hiện và kiểu truy cập bộ nhớ được thực thi thì không phụ thuộc vào dữ liệu bí mật và nếu các hướng dẫn cụ thể được biết là mất một lượng thời gian khác nhau (hoặc đầu vào của chúng bị che đi hy vọng loại bỏ mối tương quan), nó có lẽ đủ tốt. Ngoài ra, bạn thực sự chỉ cần đo nó.
Ilmari Karonen

2
Một chiếc 68020 là một con thú phức tạp ... hãy thử MCS51 ....
rackandboneman

29

Bạn không thể làm điều này nói chung, nhưng trong một số giác quan, bạn rất có thể, và đã có một vài trường hợp lịch sử mà bạn thực sự phải làm.

Các Atari 2600 (hoặc Atari Video của hệ thống máy tính) là một trong những hệ thống video gia đình trò chơi sớm nhất và lần đầu tiên được phát hành vào năm 1978. Không giống như các hệ thống sau của thời đại, Atari không thể đủ khả năng để cung cấp cho các thiết bị một bộ đệm khung hình, có nghĩa là CPU có để chạy mã ở mọi đường quét để xác định những gì sẽ tạo ra - nếu mã này mất hơn 17,08 micro giây để chạy (khoảng HBlank), đồ họa sẽ không được đặt đúng trước khi đường quét bắt đầu vẽ chúng. Tồi tệ hơn, nếu lập trình viên muốn vẽ nội dung phức tạp hơn những gì Atari thường cho phép, họ phải đo thời gian chính xác để được hướng dẫn và thay đổi các thanh ghi đồ họa khi chùm tia được vẽ, với nhịp 57,29 micro giây cho toàn bộ đường quét.

Tuy nhiên, Atari 2600, giống như nhiều hệ thống khác dựa trên 6502, có một tính năng rất quan trọng cho phép quản lý thời gian cẩn thận cần thiết cho kịch bản này: CPU, RAM và tín hiệu TV đều chạy đồng hồ dựa trên cùng một bản gốc đồng hồ. Tín hiệu TV đã tắt xung nhịp 3,98 MHz, chia số lần ở trên thành số "đồng hồ màu" số nguyên quản lý tín hiệu TV và một chu kỳ của đồng hồ CPU và RAM chính xác là ba đồng hồ màu, cho phép đồng hồ của CPU được một thước đo chính xác của thời gian liên quan đến tín hiệu TV tiến độ hiện tại. (Để biết thêm thông tin về điều này, hãy xem Hướng dẫn lập trình viên Stella , được viết cho trình giả lập Stella Atari 2600 ).

Ngoài ra, môi trường hoạt động này có nghĩa là mọi lệnh CPU đều có một số chu kỳ xác định mà nó sẽ thực hiện trong mọi trường hợp và nhiều nhà phát triển 6502 đã công bố thông tin này trong các bảng tham chiếu. Ví dụ, hãy xem xét mục này cho hướng dẫn CMP(So ​​sánh bộ nhớ với bộ tích lũy), được lấy từ bảng này :

CMP  Compare Memory with Accumulator

     A - M                            N Z C I D V
                                    + + + - - -

     addressing    assembler    opc  bytes  cycles
     --------------------------------------------
     immediate     CMP #oper     C9    2     2
     zeropage      CMP oper      C5    2     3
     zeropage,X    CMP oper,X    D5    2     4
     absolute      CMP oper      CD    3     4
     absolute,X    CMP oper,X    DD    3     4*
     absolute,Y    CMP oper,Y    D9    3     4*
     (indirect,X)  CMP (oper,X)  C1    2     6
     (indirect),Y  CMP (oper),Y  D1    2     5*

*  add 1 to cycles if page boundary is crossed

Sử dụng tất cả các thông tin này, Atari 2600 (và 6502 nhà phát triển khác) có thể xác định chính xác thời gian mã của họ thực hiện và xây dựng các thói quen làm những gì họ cần và vẫn tuân thủ các yêu cầu về thời gian tín hiệu TV của Atari. Và vì thời điểm này rất chính xác (đặc biệt là các hướng dẫn lãng phí thời gian như NOP), họ thậm chí có thể sử dụng nó để sửa đổi đồ họa khi chúng được vẽ.


Tất nhiên, 6502 của Atari là một trường hợp rất cụ thể và tất cả điều này chỉ có thể vì hệ thống có tất cả những điều sau đây:

  • Một chiếc đồng hồ chủ chạy mọi thứ, kể cả RAM. Các hệ thống hiện đại có đồng hồ độc lập cho CPU và RAM, với đồng hồ RAM thường chậm hơn và cả hai không nhất thiết phải đồng bộ.
  • Không có bộ nhớ đệm dưới bất kỳ hình thức nào - 6502 luôn truy cập DRAM trực tiếp. Các hệ thống hiện đại có bộ đệm SRAM khiến cho việc dự đoán trạng thái khó khăn hơn - trong khi có lẽ vẫn có thể dự đoán hành vi của hệ thống với bộ đệm, điều này chắc chắn khó khăn hơn.
  • Không có chương trình nào khác chạy đồng thời - chương trình trên hộp mực có toàn quyền kiểm soát hệ thống. Các hệ thống hiện đại chạy nhiều chương trình cùng một lúc bằng các thuật toán lập lịch không xác định.
  • Tốc độ đồng hồ đủ chậm để tín hiệu có thể truyền qua hệ thống kịp thời. Trên một hệ thống hiện đại có tốc độ xung nhịp 4 GHz (chẳng hạn), phải mất một photon ánh sáng 6,67 chu kỳ đồng hồ để đi hết chiều dài của bo mạch chủ nửa mét - bạn không bao giờ có thể mong đợi bộ xử lý hiện đại sẽ tương tác với một thứ khác trên bo mạch chỉ trong một chu kỳ, vì phải mất hơn một chu kỳ để tín hiệu trên bảng thậm chí đến được thiết bị.
  • Tốc độ xung nhịp được xác định rõ, hiếm khi thay đổi (1,19 MHz trong trường hợp của Atari) - tốc độ CPU của các hệ thống hiện đại luôn thay đổi, trong khi Atari không thể làm điều này mà không ảnh hưởng đến tín hiệu TV.
  • Thời gian chu kỳ được công bố - x86 không xác định thời gian của bất kỳ hướng dẫn nào.

Tất cả những điều này kết hợp với nhau để tạo ra một hệ thống trong đó có thể tạo ra các bộ hướng dẫn mất một khoảng thời gian chính xác - và đối với ứng dụng này, đó chính xác là những gì được yêu cầu. Hầu hết các hệ thống không có mức độ chính xác này đơn giản chỉ vì không cần nó - các tính toán được thực hiện khi chúng hoàn thành hoặc nếu cần một lượng thời gian chính xác, một chiếc đồng hồ độc lập có thể được truy vấn. Nhưng nếu nhu cầu là đúng (chẳng hạn như trên một số hệ thống nhúng), nó vẫn có thể xuất hiện và bạn sẽ có thể xác định chính xác thời gian mã của bạn chạy trong các môi trường này.


Và tôi cũng nên thêm từ chối trách nhiệm lớn rằng tất cả những điều này chỉ áp dụng cho việc xây dựng một bộ hướng dẫn lắp ráp sẽ mất một khoảng thời gian chính xác. Nếu những gì bạn muốn làm là lấy một số phần lắp ráp tùy ý, ngay cả trong các môi trường này và hỏi "Việc này sẽ mất bao lâu để thực thi?", Bạn hoàn toàn không thể làm điều đó - đó là Vấn đề Ngừng , đã được chứng minh là không thể giải quyết được.


EDIT 1: Trong phiên bản trước của câu trả lời này, tôi đã nói rằng Atari 2600 không có cách nào để thông báo cho bộ xử lý biết tín hiệu của TV ở đâu, điều đó buộc nó phải giữ cho toàn bộ chương trình được tính và đồng bộ hóa ngay từ đầu. Như tôi đã chỉ ra trong các nhận xét, điều này đúng với một số hệ thống như ZX Spectrum, nhưng không đúng với Atari 2600, vì nó chứa một thanh ghi phần cứng tạm dừng CPU cho đến khi xảy ra khoảng trống ngang tiếp theo, cũng như một chức năng để bắt đầu khoảng trống dọc theo ý muốn. Do đó, vấn đề đếm chu kỳ được giới hạn ở mỗi đường quét và chỉ trở nên chính xác nếu nhà phát triển muốn thay đổi nội dung khi đường quét đang được vẽ.


3
Cũng cần lưu ý rằng hầu hết các trò chơi không hoạt động hoàn hảo - bạn có thể thấy nhiều tạo tác trong đầu ra video do thời gian không khớp của tín hiệu video, do lỗi lập trình viên (ước tính không chính xác về thời gian của CPU) hoặc đơn giản là có quá nhiều công việc phải làm Nó cũng rất dễ hỏng - nếu bạn cần sửa lỗi hoặc thêm các tính năng mới, rất có thể bạn sẽ phá vỡ thời gian, đôi khi không thể tránh khỏi. Thật là vui, nhưng cũng là một cơn ác mộng :) Tôi thậm chí không chắc là tốc độ đồng hồ luôn luôn chính xác hay không - ví dụ như quá nóng, nhiễu, v.v. Nhưng nó chắc chắn cho thấy rằng nó rất khó ngay cả khi đó.
Luaan

1
Câu trả lời hay, mặc dù tôi muốn nói với bạn rằng bạn không cần phải đếm số chu kỳ cho mỗi hướng dẫn trên Atari 2600. Nó có hai tính năng giúp bạn không phải làm điều đó: Đồng hồ đếm ngược mà bạn khởi tạo và sau đó thăm dò để xem liệu nó đã đạt đến 0 chưa, và một thanh ghi tạm dừng CPU cho đến khi bắt đầu xóa ngang tiếp theo. Nhiều thiết bị khác, như ZX Spectrum, không có bất cứ thứ gì như vậy và bạn thực sự phải đếm từng chu kỳ chi tiêu sau khi ngắt trống dọc để biết bạn đang ở đâu trên màn hình.
Martin Vilcans

1
Tôi cho rằng vấn đề Ngừng không áp dụng đúng với Atari. Nếu bạn loại trừ khả năng I / O của Atari và giới hạn nó trong ROM hộp mực thông thường, thì sẽ có một lượng lưu trữ hữu hạn. Tại thời điểm đó, bạn có một máy trạng thái hữu hạn, vì vậy bất kỳ chương trình nào trên đó phải tạm dừng hoặc nhập trạng thái mà nó đã nhập trước đó, dẫn đến một vòng lặp vô hạn có thể chứng minh được trong thời gian hữu hạn.
dùng1937198

1
@ user1937198 128 byte trạng thái (cộng với bất cứ thứ gì có trong thanh ghi) là THÊM thì không gian trạng thái đủ để tạo ra sự khác biệt giữa băng đó và băng vô hạn lý thuyết của máy Turing là một điểm khác biệt chỉ trong vấn đề lý thuyết. Chết tiệt, thực tế chúng ta không thể tìm kiếm 128 BITS của một cái gì đó giống như khóa AES .... Không gian trạng thái phát triển nhanh chóng khi bạn thêm bit. Đừng quên rằng tương đương với 'Vô hiệu hóa các ngắt; dừng lại 'sẽ gần như chắc chắn có thể.
Dan Mills

1
"đó là vấn đề dừng, đã được chứng minh là không thể giải quyết được. Nếu bạn gặp phải vấn đề này, thì bạn cần phải thoát ra khỏi đồng hồ bấm giờ và thực sự chạy mã của mình." - điều này không có ý nghĩa. Bạn không thể trốn tránh bằng chứng của Turing bằng cách "thực sự" chạy mã thay vì mô phỏng nó. Nếu nó dừng lại, bạn có thể mất bao lâu để dừng lại. Nếu nó không dừng lại, bạn không bao giờ có thể chắc chắn (nói chung) liệu nó sẽ dừng lại trong tương lai hay chạy mãi mãi. Đó là vấn đề tương tự với đồng hồ bấm giờ thật hoặc giả. Ít nhất là trong một mô phỏng, bạn có thể dễ dàng kiểm tra trạng thái bên trong hơn cho các dấu hiệu của vòng lặp.
benrg

15

Có hai khía cạnh chơi ở đây

Như @ gnasher729 chỉ ra, nếu chúng ta biết các hướng dẫn chính xác để thực hiện, thì vẫn khó ước tính thời gian chạy chính xác vì những thứ như bộ đệm, dự đoán nhánh, chia tỷ lệ, v.v.

Tuy nhiên, tình hình thậm chí còn tồi tệ hơn. Với một khối lắp ráp, không thể biết hướng dẫn nào sẽ chạy hoặc thậm chí để biết có bao nhiêu hướng dẫn sẽ chạy. Điều này là do định lý của Rice: nếu chúng ta có thể xác định chính xác điều đó, thì chúng ta có thể sử dụng thông tin đó để giải quyết vấn đề Ngừng, điều này là không thể.

Mã hội có thể chứa các bước nhảy và các nhánh, đủ để làm cho dấu vết đầy đủ của một chương trình có thể là vô hạn. Đã có nghiên cứu về các xấp xỉ bảo thủ về thời gian thực hiện, đưa ra các giới hạn cao hơn về thực thi, thông qua những thứ như ngữ nghĩa chi phí hoặc các hệ thống loại chú thích. Tôi không quen thuộc với bất cứ điều gì để lắp ráp cụ thể nhưng tôi sẽ không ngạc nhiên nếu một cái gì đó như thế tồn tại.


4
Ý tôi là, Vấn đề tạm dừng áp dụng trực tiếp tại đây, vì nếu chúng ta biết thời gian chạy chúng ta sẽ biết nếu nó dừng lại. Ngoài ra, thực tế là không có điều kiện nào thậm chí không giúp đỡ ở đây, vì trong x86, movlà Turing-Complete
BlueRaja - Danny Pflughoeft

7
Rice và Vấn đề dừng là các tuyên bố về các chương trình tùy ý (bất kỳ) - nhưng OP ở đây đã chỉ định một đoạn mã cụ thể trong câu hỏi. Bạn có thể xác định các thuộc tính ngữ nghĩa và tạm dừng về các loại chương trình riêng lẻ hoặc giới hạn, phải không? Chỉ là không có quy trình chung bao gồm tất cả các chương trình.
Daniel R. Collins

2
Chúng tôi có thể dứt khoát biết mà hướng dẫn sẽ chạy tới, những gì chúng ta không thể nói là nếu chúng ta bao giờ đạt mức sys_exitvà do đó ngăn chặn đồng hồ bấm giờ. Nếu chúng tôi hạn chế chấm dứt các chương trình, điều này hợp lý cho một câu hỏi thực tế như vậy, thì câu trả lời thực sự là có (với điều kiện bạn có một ảnh chụp hoàn hảo về trạng thái, hw và sw, của hệ thống ngay trước khi bắt đầu chương trình).
Margaret Bloom

1
@ BlueRaja-DannyPflughoeft Mov đã hoàn tất, nhưng không phải là đoạn mã mà OP có ở đây. Nhưng dù sao đi nữa, bên cạnh vấn đề - các ints có thể thực thi mã tùy ý, chờ các hoạt động I / O tùy ý, v.v.
Luaan

2

Sự lựa chọn "hệ thống máy tính" có xảy ra bao gồm cả vi điều khiển không? Một số bộ vi điều khiển có thời gian thực hiện rất dễ đoán, ví dụ chuỗi PIC 8 bit có bốn chu kỳ xung nhịp cho mỗi lệnh trừ khi lệnh hướng đến một địa chỉ khác, đọc từ flash hoặc là một lệnh hai từ đặc biệt.

Ngắt sẽ làm gián đoạn loại timimg này nhưng có thể làm được rất nhiều mà không cần một trình xử lý ngắt trong cấu hình "kim loại trần".

Sử dụng lắp ráp và một kiểu mã hóa đặc biệt, có thể viết mã sẽ luôn mất cùng thời gian để thực thi. Hiện tại, hầu hết các biến thể PIC đều có nhiều bộ định thời, nhưng điều đó là có thể.


2

Quay lại thời đại của máy tính 8 bit, một số trò chơi đã làm một cái gì đó như thế. Các lập trình viên sẽ sử dụng lượng thời gian chính xác cần thiết để thực hiện các hướng dẫn, dựa trên lượng thời gian họ sử dụng và tốc độ xung nhịp đã biết của CPU, để đồng bộ hóa với thời gian chính xác của phần cứng video và âm thanh. Quay trở lại những ngày đó, màn hình là một màn hình ống tia âm cực sẽ quay vòng qua từng dòng màn hình với tốc độ cố định và vẽ hàng pixel đó bằng cách bật và tắt tia catốt để kích hoạt hoặc hủy kích hoạt các photpho. Bởi vì các lập trình viên cần nói với phần cứng video những gì sẽ hiển thị ngay trước khi chùm tia chạm tới phần đó của màn hình và điều chỉnh phần còn lại của mã vào bất cứ lúc nào còn sót lại, họ gọi đó là cuộc đua của chùm tia.

Nó hoàn toàn không hoạt động trên bất kỳ máy tính hiện đại nào, hoặc cho mã như ví dụ của bạn.

Tại sao không? Dưới đây là một số điều sẽ làm xáo trộn thời gian đơn giản, có thể dự đoán được:

Tốc độ CPU và tìm nạp bộ nhớ đều là nút cổ chai về thời gian thực hiện. Thật lãng phí tiền để chạy CPU nhanh hơn nó có thể tìm nạp các lệnh để thực thi hoặc để cài đặt bộ nhớ có thể phân phối byte nhanh hơn CPU có thể chấp nhận chúng. Bởi vì điều này, các máy tính cũ chạy cả hai cùng một đồng hồ. CPU hiện đại chạy nhanh hơn nhiều so với bộ nhớ chính. Họ quản lý điều đó bằng cách lưu trữ hướng dẫn và dữ liệu. CPU sẽ vẫn bị đình trệ nếu cần phải đợi các byte không có trong bộ đệm. Do đó, các hướng dẫn tương tự sẽ chạy nhanh hơn nhiều nếu chúng đã có trong bộ đệm so với khi không có.

Hơn nữa, CPU hiện đại có đường ống dài. Họ giữ thông lượng cao bằng cách có một phần khác của chip thực hiện công việc sơ bộ theo một số hướng dẫn tiếp theo trong đường ống. Điều này sẽ thất bại nếu CPU không biết hướng dẫn tiếp theo sẽ là gì, điều này có thể xảy ra nếu có một nhánh. Do đó, CPU cố gắng dự đoán các bước nhảy có điều kiện. (Bạn không có bất kỳ trong đoạn mã này, nhưng có lẽ đã có một bước nhảy có điều kiện mispredicted để nó gây tắc nghẽn đường ống. Bên cạnh đó, lý do tốt để liên kết câu trả lời huyền thoại.) Tương tự, hệ thống gọi int 80để bẫy vào chế độ hạt nhân thực sự đang sử dụng một tính năng CPU phức tạp, một cổng ngắt, gây ra sự chậm trễ không thể đoán trước.

Nếu hệ điều hành của bạn sử dụng đa nhiệm được ưu tiên, luồng chạy mã này có thể mất thời gian của nó bất cứ lúc nào.

Đua chùm tia cũng chỉ hoạt động vì chương trình đang chạy trên kim loại trần và đập trực tiếp vào phần cứng. Ở đây, bạn đang gọi int 80để thực hiện một cuộc gọi hệ thống. Điều đó vượt qua sự kiểm soát đối với hệ điều hành, điều này cho phép bạn không đảm bảo thời gian. Sau đó, bạn nói với nó làm I / O trên một luồng tùy ý, có thể đã được chuyển hướng đến bất kỳ thiết bị nào. Nó quá trừu tượng đối với bạn để nói I / O mất bao nhiêu thời gian, nhưng chắc chắn nó sẽ chi phối thời gian thực hiện các hướng dẫn.

Nếu bạn muốn thời gian chính xác trên một hệ thống hiện đại, bạn cần phải giới thiệu một vòng lặp trì hoãn. Bạn phải làm cho các vòng lặp nhanh hơn chạy ở tốc độ chậm nhất, điều ngược lại là không thể. Một lý do khiến mọi người làm như vậy trong thế giới thực là để ngăn chặn rò rỉ thông tin mật mã cho kẻ tấn công có thể mất thời gian yêu cầu lâu hơn những người khác.


1

Điều này có phần tiếp tuyến nhưng tàu con thoi có 4 máy tính dự phòng phụ thuộc vào việc được đồng bộ hóa chính xác, tức là thời gian chạy của chúng khớp chính xác.

Nỗ lực khởi động đầu tiên của tàu con thoi vũ trụ đã bị loại bỏ khi máy tính Sao lưu phần mềm (BFS) từ chối đồng bộ hóa với bốn máy tính Hệ thống phần mềm điện tử chính (PASS). Chi tiết trong "Con bọ nghe vòng quanh thế giới" tại đây . Đọc hấp dẫn về cách phần mềm được phát triển để phù hợp với chu kỳ và có thể cung cấp cho bạn nền tảng thú vị.


0

Tôi nghĩ rằng chúng ta đang trộn lẫn hai vấn đề khác nhau ở đây. (Và vâng, tôi biết điều này đã được người khác nói, nhưng tôi hy vọng tôi có thể diễn đạt rõ ràng hơn.)

Trước tiên, chúng ta cần chuyển từ mã nguồn sang chuỗi các hướng dẫn thực sự được thực thi (cần kiến ​​thức về dữ liệu đầu vào cũng như mã - bạn đi vòng quanh bao nhiêu lần? Chi nhánh nào được thực hiện sau khi kiểm tra? ). Do vấn đề tạm dừng, chuỗi hướng dẫn có thể là vô hạn (không kết thúc) và bạn luôn không thể xác định điều đó một cách tĩnh, ngay cả với kiến ​​thức về dữ liệu đầu vào.

Khi đã thiết lập chuỗi các hướng dẫn sẽ được thực hiện, sau đó bạn muốn xác định thời gian thực hiện. Điều đó chắc chắn có thể được ước tính với một số kiến ​​thức về kiến ​​trúc hệ thống. Nhưng vấn đề là trên nhiều máy hiện đại, thời gian thực hiện phụ thuộc rất nhiều vào bộ nhớ đệm của bộ nhớ, điều đó có nghĩa là nó phụ thuộc nhiều vào dữ liệu đầu vào như các hướng dẫn được thực hiện. Nó cũng phụ thuộc vào việc đoán chính xác các điểm đến chi nhánh có điều kiện, một lần nữa phụ thuộc vào dữ liệu. Vì vậy, nó sẽ chỉ là một ước tính, nó sẽ không chính xác.

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.