Чи потрібно розуміти, що відбувається на апаратному рівні, щоб бути хорошим програмістом?


24

Я програміст-самоучок, на всякий випадок, коли на це запитання відповіли в CS 101. Я вивчив і використовував багато мов, здебільшого для власного особистого використання, але іноді і для професійних занять.

Здається, я завжди натрапляю на одну стіну, коли натрапляю на програмування проблем. Наприклад, я просто задав запитання на іншому форумі про те, як обробляти вказівник на масив, який повертається функцією. Спочатку я думаю, що просто не знаю належної техніки, яку створили дизайнери C ++ для вирішення ситуації. Але з відповідей та обговорень, які випливають, я бачу, що я насправді не отримую того, що відбувається, коли щось "повертається".

Якого глибокого рівня розуміння процесу програмування повинен досягти хороший програміст?


3
Моя порада: вивчіть деяку збірку x86 (DOS або інше). Потім навчіться читати деякі результати асемблера деяких невеликих фрагментів коду С. Задавайте питання, якщо ви не розумієте вихід. Повторіть. Це змусить вас зрозуміти, що відбувається на рівні процесора
граф


Earlz - Ви маєте на увазі, що я повинен навчитися програмувати за допомогою набору інструкцій x86? Це "рівень процесора"?
bev

Робота - thx, це було весело. Він насправді допустив декілька помилок, тх, просто FYI.
bev

Відповіді:


33

Ні. Ніхто не розуміє, що відбувається на апаратному рівні.

Комп'ютерні системи схожі на цибулю - багато шарів, і кожен залежить від шару під ним для підтримки. Якщо ви хлопець, який працює над одним із зовнішніх шарів, вам не надто турбуватиметься те, що відбувається в середині цибулі. І це добре, адже середина цибулі завжди змінюється. Поки шар або шари, які підтримують ваш конкретний шар, продовжують виглядати однаково і підтримують ваш шар, ви добре.

Але потім знову ...

Так. Я маю на увазі, вам не потрібно розуміти, що насправді відбувається всередині цибулі, але це дуже допомагає скласти ментальну модель того, як виглядає внутрішня частина типової цибулі. Можливо, не найглибша частина, де у вас є ворота, складені з транзисторів і подібних, або наступний або два шари, де у вас є мікрокод, годинник, інструкції з декодування інструкцій і т. Д. Наступні шари - де ви У вас є регістри, стек і купа. Це найглибші шари, де ти маєш великий вплив на те, що відбувається - компілятор переводить ваш код в інструкції, які працюють на цьому рівні, і якщо ти хочеш, ти можеш зазвичай переглядати ці інструкції і дізнатися, що "насправді" відбувається.

Більшість досвідчених програмістів мають в голові трохи казкову версію цих шарів. Вони допомагають вам зрозуміти, про що говорить компілятор, коли він повідомляє, що сталося "недійсне виключення адреси" або "помилка переповнення стека" чи щось подібне.

Якщо вам цікаво, прочитайте книгу про архітектуру комп’ютера. Це навіть не повинно бути особливо новою книгою - цифрові комп'ютери працюють приблизно однаково вже тривалий час. Чим більше ви дізнаєтесь про внутрішню частину цибулі, тим більше вас здивує те, що будь-який із цих матеріалів взагалі працює! Вивчення (приблизно) того, що відбувається в нижчих шарах, робить програмування менш таємничим і, якось, більш магічним. І справді, веселіше.

Ще одна річ, на яку ви можете заглянути, - це вбудована цибуля. Е, я маю на увазі вбудовані системи. Існує ряд вбудованих платформ, які досить прості у використанні: Arduino та BASIC Stamp - два приклади. Це в основному невеликі мікропроцесори з великою кількістю вбудованих функцій. Ви можете вважати їх цибулею з меншою кількістю шарів, ніж ваш типовий настільний ПК, тож можна досить глибоко зрозуміти, що відбувається у всій системі, від апаратного забезпечення до програмного забезпечення.


2
Спасибі. Це в основному відповідає на моє запитання. Я EE, який зробив дизайн мікросхеми (тобто транзисторного рівня) реєстрів, суматорів, мультиплексорів тощо, тому я отримую найнижчий рівень (якщо ми не говоримо про квантову механіку). Я також можу досить добре використовувати мови, які я знаю. У мене просто величезна прогалина на середньому рівні (стек, купа), де ви кажете, що компілятор робить свою роботу. Оскільки, як ви сказали, я хочу, щоб мій досвід програмування був "менш загадковим і, ..., більш магічним". здається, що я повинен вивчити рівні, які мені ще невідомі.
bev

@bev: У такому випадку вам справді слід перевірити платформу типу Arduino.
Калеб

вибачте, що тьмяний, але я перевірив Arduino, і я не можу реально зрозуміти, як його використання допоможе мені зрозуміти, як компілятор по-різному ставиться до покажчиків та масивів. Чого я не бачу?
bev

@bev: Якщо ви просто хочете дізнатись, як викликаються функції, ви, ймовірно, можете витратити 30 хвилин на те, щоб прочитати про це і зробити це. Якщо ви хочете краще зрозуміти, як все працює разом, найлегше буде з невеликою системою. Це найкращий спосіб одразу отримати всю цибулю в голові. AVR, сімейство чіпів, на яких базується Arduino, - це приємна загальна мета, проста у користуванні система з набором інструкцій, який досить малий, щоб навчитися без особливих проблем.
Калеб

Ну, тоді добре. Домашня сторінка трохи мутна щодо цього аспекту їх продукції. Я ще раз погляну.
bev

10

Ви не говорите про апаратний рівень, ви говорите про те, що компілятор насправді робить з тим, що ви йому говорите.

Вам, безумовно, потрібен цей рівень розуміння для того, щоб зрозуміти, що пішло не так, коли це не очевидно, особливо коли йдеться про ситуацію з тупою пам'яті.


Лорен - Так! Дякую за просту правду. Тепер мені потрібно знайти найкращий спосіб дізнатися, що компілятори c ++ роблять зі своїми типами даних. До речі, як EE, я знаю, що це не апаратний рівень буквально. Я просто не знав, як ви називаєте це визирки CS. (Все ще не з цього приводу. Рівень компілятора?)
bev

BTW - шум пам'яті?
bev

@Bev: Ви щойно довели мою думку - якщо ви навіть не знаєте, що це за пам'ять, у вас буде жахливий час, коли ви знайдете помилку через одну. Тупання пам’яті - це коли щось записує до місця, яке не повинно, і стирає (тупає), що там сталося. Якщо вам пощастить, все, що вам вдарилося, було негайно життєво важливим і, принаймні, воно підірветься. Якщо вам не пощастило, програма просто продовжує робити деякі отвори у своїх даних.
Лорен Печтел

дякую за роз’яснення Це також показує мені, наскільки я не знаю, оскільки, наскільки я знаю, я просто пишу до купи або стека, не маючи більш точного контролю.
bev

@Bev: Проблема виникає, коли ти пишеш там, де не думаєш, що пишеш. У вас є щось на стеці, і ви робите вказівник на нього. Ви залишаєте рутину - елемент відходить, вказівник - ні. Тепер, що відбувається, коли ви пишете на цей покажчик ?? Або у вас є масив із 100 елементів - що станеться, коли ви пишете на елемент № 200?
Лорен Печтел

6

Розуміння пам'яті програми! = Розуміння апаратного забезпечення

Розуміння ієрархії пам'яті == Розуміння обладнання


Щоб відповісти на ваше загальне запитання: Це залежить. Це не завадить зрозуміти апаратне забезпечення, але розуміння цього не допоможе у всіх випадках.

Виходячи з вашого прикладу, вам просто потрібно зрозуміти, як поділяється пам'ять і як вона організована під час запуску програми. Розуміння обладнання не допоможе вам у цьому плані, оскільки пам'ять (як видно програмі) навіть не по-справжньому представляє апаратне забезпечення завдяки магії віртуальної пам'яті.

Якщо вам цікаво питання щодо продуктивності, залежно від порядку, в якому ви отримуєте доступ до пам’яті, ЗАРАЗ ви отримаєте користь від розуміння апаратних засобів, ієрархії пам’яті, помилок кеш-пам'яті, помилок сторінки та всієї чудової чудової користі, яка виходить із обладнання.


Stargazer - Я ще не в тій точці, де можу переживати з питаннями продуктивності. Скоро, сподіваємось. Дякую за коментарі
березень

5

Якщо ви дійсно вирішили дізнатися трохи асемблера, ймовірно , ви повинні дізнатися що - щось на зразок 6502 асемблера на Commodore 64 (емулювати, звичайно), або 68000 на Amiga.

Ви можете ознайомитись з Commodore 64 тут ...

http://thepiratebay.org/torrent/4609238/Tag3-Saal2-Slot16_00--ID2874-the_ultimate_commodore_64_talk-Main

Класична книга все, що вам потрібно знати, - це описана тут ...

http://reprog.wordpress.com/2010/03/12/programming-books-part-3-programming-the-commodore-64/

Ви, ймовірно, можете знайти сканування PDF, якщо оглянетесь.

IMO, 6502 простіше, ніж Z80, а 68000 легше, ніж 8086 - більш регулярні набори інструкцій тощо.

Але процесор - це лише один аспект апаратного забезпечення. Також сучасний процесор є масово іншим звіром, і він робить прозорі навіть з точки зору компіляторів - наприклад, презентацію віртуального адресного простору.

Особлива перевага 6502 на C64 полягає в тому, що не тільки простий процесор, але є і дуже прості для злому апаратне обладнання. Раніше мені було весело грати з музичним чіпом SID.

Отже - це, мабуть, гідна вправа, якщо ви не витрачаєте на це занадто багато часу. Я засвоїв асемблер 6502 як свою другу мову, коли мені було близько 14 років, відразу після Commodore Basic. Але в основному це виходить дуже проста робоча модель, щоб ви могли додати до неї більш складні ідеї з мінімальним непорозумінням.

Деякі корисні речі ви можете дізнатися, працюючи в асемблері ...

  • Як працюють регістри процесора.
  • Як працює адресація пам'яті, включаючи непряме.
  • Як працює стек процесора
  • Як працює бітова логіка.
  • Як ЦП контролює пристрої вводу / виводу.
  • Як працюють переривання.

Один із конкретних причин, який я рекомендую, - це краще зрозуміти, як прості кроки діють цілком детерміновано та механічно та зовсім без інтелекту чи здорового глузду. В основному звикання до імперативної моделі виконання в її найчистішій і впертісінькій формі невігласу.

Точно наскільки корисно знати більшість цих речей зараз, проте це складне питання.

Одне, чого ви не навчитесь, - це як добре грати зі спадщиною пам’яті. Ці старі машини здебільшого мали просту модель пам’яті, без шарів кешу та без віртуальної пам’яті. Ви також багато чого не дізнаєтесь про одночасність - це, безумовно, були способи впоратися з цим, але це переважно означало перебої. Вам не потрібно було турбуватися про мютекси тощо.

Іноді ментальна модель того, як ці речі колись працювали, або про те, як працює асемблер, навіть може ввести в оману. Наприклад, мислення покажчика С як адреси може призвести до невизначених проблем з поведінкою. Покажчик змінного струму зазвичай реалізується як ціле число, що містить адресу, але немає гарантії, що це абсолютно вірно. Наприклад, на деяких химерних платформах різні вказівники можуть вказувати на різні адресні простори. Це стає важливим, коли ви хочете робити арифметичні або бітові логічні з двома вказівниками.

Якщо у вас немає однієї з цих химерних платформ, ви, можливо, не думаєте, що вас це турбує, - але компілятори в наші дні все частіше використовують оптимізовану для стандартів поведінку.

Отже, ментальна модель архітектури системи може бути корисною, але все одно важливо кодувати специфікацію мови, а не гіпотетичну модель, яку ваша мова та платформа можуть не дотримуватися.

Нарешті, багато корисних ментальних моделей походить від отримання уявлення про те, як компілятори генерують код - а генерація коду для сучасних мов сильно відрізняється від досить тривіальних компіляторів, доступних тоді.

Це улюблена моя книга для цього ...

http://dickgrune.com/Books/MCD_1st_Edition/

Поряд із деталями розбору та AST тощо він охоплює генерацію коду для різних мовних парадигм - імперативних, OOP, функціональних, логічних, паралельних та розподілених - а також для управління пам'яттю. Якщо ви хочете знати, як працюють виклики поліморфних методів, не забиваючись у деталі набору інструкцій процесора, така книга, як ця, є вашим другом - і незабаром вийде нове видання.


Стів - вау. Я поруч безмовна, з повнотою та фокусом вашої відповіді на моє запитання. Велике спасибі, що знайшли час, щоб написати всю цю справу. Я обов'язково прийму ваші пропозиції.
bev

1
Я б припустив, що асемблер PDP-11 трохи приємніше вчитися, ніж усі інші згадані. Навчають усі інші - обмеження, вимушені обмеженими апаратними ресурсами, та / або обмеженою конструкцією та продуманою технікою. Щось на кшталт однієї із надто поширених сімейств 8051 вчить, як насправді химерна модель програмування може потрапляти на таке обмежене обладнання (де, наприклад, згадується Стів про різні адресні простори).
Грег А. Вудс

@Greg - Боюся, я ніколи не грав з PDP-11. Ні 8051 - я деякий час вкладав роботу, але використовував чіп сімейства 8096. Я просто подивився тут хоч - цікаво. Я чув про гарвардську архітектуру раніше, але не мав уявлення, що є щось подібне, яке було дуже популярним і досі використовується.
Steve314

4

Двадцять років тому це було важливо, але зараз не так вже й багато - є набагато більше шарів абстракції між програмним забезпеченням та сучасним обладнанням.

Корисно знати такі речі, як потреба в декількох потоках, щоб скористатись декількома ядрами, або те, що використання більшої кількості пам'яті, ніж існує в системі, є поганою справою, але крім цього вам це дійсно не потрібно, якщо це не ваша робота, щоб написати ці абстракції шарами.

Решта вашого запитання говорить про те, що ви, можливо, більше переймаєтесь компілятором, ніж апаратними засобами, що дещо відрізняється. Ви можете зіткнутися з випадками, коли це важливо, але вони, як правило, або тривіальні (нескінченна рекурсія працює не дуже добре), або ж такі випадкові випадки, коли ви можете добре вирішити її, але, ймовірно, ніколи не зіткнетесь з тією ж проблемою. знову.


Так, ти маєш рацію, я більше переймаюся компілятором. Крім того, thx для вашої пропозиції щодо декількох потоків, декількох ядер тощо. Це просто увійшло до мого файлу приміток toLearn.
bev

@bev багатопотоковість легко вивчити, просто не робіть цього, якщо вам справді не доведеться і навіть тоді цього не робите. більше моїх клопотів, ніж її варто
Скайт

@Skeith - дякую за пораду. Я буду мати це на увазі.
bev

4

Це дуже допомагає знати та розуміти абстракцію, представлене обладнанням, і трохи загального уявлення про те, як створюється ця ілюзія, - але намагатися по-справжньому зрозуміти, як справді працює сучасне обладнання - це величезна робота, з якої ви ' Ви, ймовірно, побачите лише мінімальний прибуток.

Якщо ви простите про незначну диверсію: це нагадує мені те, що я зазначив кілька років тому. Десятиліття тому (аж до кінця 1970-х років) більшість людей вважали, що комп’ютери не мають жодного кроку від магічного - навряд чи впливають закони фізики, здатні до будь-яких речей, що мають мало реального сенсу тощо. У той час я витратив досить багато часу, намагаючись переконати людей, що ні, вони не були магією. Це були справді досить звичайні машини, які робили обмежену кількість речей дуже швидко та надійно, але в іншому випадку були надзвичайно мирськими.

У наш час погляд більшості людей на комп'ютери змінився. Зараз вони досить звичайні - до того, що досить багато звичайних людей їх практично розуміють. Наприклад, деякий час назад, коли я вечеряв, я побачив / почув офіціанта та офіціантку, коли вони перервались, обговорюючи, що їй слід отримати у своєму новому комп’ютері. Поради, які він давав, були цілком розумними та реалістичними.

Мій погляд на комп’ютери теж змінився. Я перейшов до «Гарячих чіпів», а до цього Форум мікропроцесорів, що повернувся до середини 1990-х років. Напевно, я знаю більше про апаратне забезпечення мікропроцесорів, ніж принаймні 99% програмістів - і знаючи, що я роблю, я скажу це: вони вже не звичайні. Вони ж майже порушують закони фізики. Я багато зробив тестування на низькому рівні, і це можу сказати точно: подолати ілюзію, створену процесором, і перетворити на рівень показу, як апаратне забезпечення дійсно працює, часто буває надзвичайно важко. Я б хотів, щоб я міг розмістити фотографію одного з наших установок із комп'ютером, похованим під кабелі не менше ніж 4 логічних аналізаторів, щоб правильно виміряти один аспект того, як кешування працює на сучасному процесорі (не кажучи вже про деякі справді вибагливі програми для забезпечення того, що те, що ми вимірювали, було саме тим, що робив процесор, і нічого іншого).


Джеррі - дякую за ваші коментарі. Будучи ЕЕ, мені комфортніше транзисторний рівень, ніж деякі вищі рівні абстракції. Мені просто цікаво, що мені потрібно знати, щоб бути хорошим програмістом на C ++.
bev

Ця картина звучить цікаво. Чому ви не можете опублікувати його?
Мейсон Уілер

@Bev: Вам не потрібно нічого знати на транзисторному рівні, щоб бути хорошим програмістом. Ці абстракції існують з причини, і ви майже завжди можете вважати що-небудь на рівні абстракції нижче рівня машинного коду / складання абсолютно неактуальним, і просто припускати, що воно працює.
Мейсон Уілер

@MasonWheeler: Я взяв його там, де я працював, але оскільки я вже не працюю там, отримати доступ до нього, можливо, буде дещо складніше (можливо, це неможливо - я кинув з добрих умов, але навіть так. ..)
Джеррі Труну

1

Різні мови працюють на різних рівнях абстрагування від апаратних засобів. C і C ++ дуже низькі. Мови сценаріїв, з іншого боку, вимагають менше знати про основні деталі.

Однак я б все-таки сказав, що в усіх випадках, чим більше ти знаєш, тим краще програмістом будеш. Частина програмування здатна жонглювати кількома рівнями абстракції одночасно.

Якщо ви програмуєте на C ++, вам потрібно добре розуміти, як працює сучасний процесор, принаймні на рівні абстракції, на якому працює компілятор. (Всередині процесора відбуваються речі, які прозорі і для компілятора).


Скотт - під «досить хорошим розумінням того, як працює сучасний процесор ..» ви маєте на увазі, як працює цифрова логіка (наприклад, як працюють карти Карнау, таблиці правди та / або / або NOR / XOR ворота)? чи ти маєш на увазі, які ресурси використовує компілятор (тобто регістри)?
bev

Знати більше - це добре. Справжній трюк - це знати, яке саме «більше» дасть найбільший удар за ваш долар. Наприклад, знаючи терміни інструкцій, не буде багато користі, коли майже неможливо передбачити, які інструкції використовуватиме ваш компілятор. Навчання використання профілера, ймовірно, дасть набагато кращі співвідношення витрат і вигод.
Steve314

1
@bev - Ні, я не думаю, що вам потрібно опускатися до рівня воріт. Якщо ви просто знали основну архітектуру (пам'ять, шина, процесор), як вона завантажує інструкцію, виконує її, зберігає результат тощо, ви, ймовірно, все в порядку. Вам також потрібно зрозуміти, як компілятор викладає простір пам’яті програми, включаючи, як він використовує стек і купу.
Скотт Вітлок

@ScottWhitlock - Спасибі - це якраз конкретні рекомендації, які я шукав.
bev

0

Я хотів би додати точку зразкового дизайну мов вищого рівня, таких як C.

Взагалі, я вважаю, що можна з упевненістю сказати, що такі мови можна розглядати як реалізацію абстрактної машини, і саме так Денніс Рітчі сам описав, як працює C, і як конкретна конструкція абстрактної машини С зробила її більш портативною мовою. Як таке розуміння архітектури комп’ютера та функціонування на рівні машини, може бути дуже корисним для розуміння абстрактної машини мови.

Портабельність програм C на папері DMR та системи UNIX - це перша, яку я пам'ятаю, щоб обговорити (абстрактну) модель машини для C.

Я вважаю, що документ DMR про історію та розвиток C також є надзвичайно корисним для показу, як реальне обладнання впливає на дизайн мови, і, можливо, є також прикладом дизайну мови раннього програмування: Розвиток мови C


Оскільки ви тут новачок, вам здається, що це форум, це, звичайно, не так. Ваші відповіді на запитання не повинні бути точкою, яку ви додаєте, яку слід відпускати до коментарів, а відповідь має бути спробою бути вичерпною відповіддю безпосередньо на питання. Це говорить про те, що ви добре зазначаєте, і це важливо для інформації про теми, можливо, якщо ви могли б поставити кілька рядків у цій відповіді на питання безпосередньо разом із цим поясненням, було б чудово. Класна інформація, якою ви тут ділитесь. Ласкаво просимо до програмістів!
Джиммі Хоффа

коментарі не є спростованими та не постійними, тому вони марні для додавання до набору відповідей. Більшість плакатів також схильні до ігнорування використання коментарів для оновлення своїх відповідей, а більшість відповідей не позначаються як відповіді "вікі спільноти", тому інші не можуть редагуватись таким чином, щоб зберегти деяку атрибуцію наступних учасників (-ів) . Крім того, саме це питання розпочало справжню дискусію, і сподобалось це, чи ні, це шлях деяких із цих питань. Намагання змусити кожен внесок в одну форму є головним провалом концепції обміну ставками.
Грег А. Вудс

і, до речі, я насправді відповідав, але невірно, на одне справжнє запитання з ОП: треба мати достатньо розуміння апаратних засобів, щоб можна було моделювати абстрактну машину в основі мовного дизайну.
Грег А. Вудс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.