最近、私(そしてほとんどの人)がVisualBasicのようなものから始めてコンピュータープログラミングを学んだことに気づきました。私は、最初に下位レベルから始めたのではないかと思い始めました。
CPUのしくみや基本的な命令などを理解することは、プログラマーとしての価値があると思いますか?結局のところ、私たちは本当にそれに話しかけているのではないのですか?
CPUレベルから始めて、そこから上に教えると、高レベルでの操作方法をより簡単に理解できることがわかるかもしれません。
それは双方向に行きます。
たとえば、より高いレベルで始めた多くの人々は、シフトが乗算や除算よりもはるかに速い理由や、分岐の影響などを知りません。
その結果、彼らはしばしば遅いが、平均的な人が理解しやすいコードを書きます。(一部のアプリケーションでは、理解しやすいことよりも速く進むことが重要であることに注意してください)
舞台裏で何が起こっているか(さまざまな操作にかかるクロックサイクル数、CPUのパイプラインの動作、キャッシュの影響など)を理解している人は、非常に高速なコードを記述できることがよくありますが、多くの人にとっては難しい場合があります。理解/維持する。(これは、「最適化」に知覚できるメリットがなく、保守性がより重要であるアプリケーションでは特に困難です)
個人的には、「下で何が起こっているのか」を知ることで、少なくとも自分が下している決定の影響を知ることができると感じています。
正直なところ、この時点では、低レベルの詳細/最適化の多くをコンパイラーに任せてもかまいません。とにかくそれはおそらく私よりも良い仕事をします:]
私は医師が私の心臓の仕組みを知っていることを期待しています (ただし、必ずしも心臓手術を行うことができるとは限りません)。整備士は私のエンジンがどのように機能するかを知っていることを期待しています (ただし、必ずしもエンジンを構築できるとは限りません)。 CPU がどのように機能するかを知っている (ただし、必ずしも CPU を構築したり、アセンブリでエンタープライズ アプリを作成したりできるわけではありません。ただし、CPU キャッシュについて議論したり、いくつかのアセンブリ コードを見たりしても、彼は丘に向かって走る必要はありません)。
私たちはプロです。通常はそのレベルで働いていなくても、「ボンネットの下」で物事がどのように機能するかを知ることが期待されています。
私は低レベルのプログラミングについてかなりのことを学びました。それは、私が作成するすべてのコードで非常に役立っていると思います。高水準言語でさえ、基本的な同期プリミティブ (ミューテックス/ロック、条件、セマフォ) のいくつかのバージョンを持っています。ディスクまたはネットワーク カードから読み取る必要があります。メモリ内のある場所から別の場所にバイトをコピーする必要があります. コンピューターが最も低いレベルでどのように機能するかを理解している場合は、その知識をいつでも適用して、プラットフォームがどれほど抽象化されていても、より効率的でバグが発生しにくいコードを作成できます。低レベルの操作に関する知識は、他の方法では学べなかったかもしれないことを教えてくれることさえあります。mutex のようなものを適切に使用する方法を学ぶには、mutex を実装するよりも良い方法はありません。(わかりました、少し誇張されているかもしれませんが、私の主張を理解していただければ幸いです)
要するに、はい、すべての抽象化レベルのプログラマーが基本について学ぶことは絶対に良い考えです。でも、始めるのが必ずしも良い考えだとは思いません基礎と一緒に。アセンブリ言語のレベルのプログラムは理解するのが難しいことで有名であり、プログラミングの初心者にそれを強要しようとすると、彼/彼女を落胆させる可能性が高いと思います. 基本的な操作を理解することは、より効率的でエラーが発生しにくいコードを作成するのに役立つと述べましたが、コードを作成する必要はまったくありません。したがって、私の意見では、ほとんどの人は、プログラミングのプロセスに慣れながら、オブジェクトなどのなじみのある概念を理解できる中間のどこかから始めるのがおそらく最善でしょう。その分野である程度の経験を積んだ後、CPU は公平なゲームです ;-)
そのように学んだプログラマーのコミュニティはまだあります。
使用しているハードウェアを認識していると、そのハードウェア用のコードを作成するための最良の方法についての優れた洞察が得られるということについては、私の考えでは議論の余地はありません。そうは言っても、私が遭遇した(そして書いた)最もハードウェア固有のコードのいくつかは、最も読みにくく、保守しにくいものでもありました。
プログラミング全般にとって、それはそれほど重要ではないと思います。ただし、パフォーマンスが重要な領域に入ると、それが重要なスキルになります。
プログラミング言語は仮想マシンです。C、C#、Fortran、Basic などは、移植可能ではありますが、それ自体が CPU です。彼らは、Fortran でプログラミングしている場合、ある種の Fortran マシンでプログラミングしていると言います。C でプログラミングしている場合は、ある種の C マシンでプログラミングしています。ハードウェア レベルで実装された言語である LISP もあります。
C に関するジョークさえあります。 C プログラミング言語 : アセンブリ言語のすべての優雅さとパワーと、アセンブリ言語のすべての読みやすさと保守性を組み合わせた言語。
C などの言語や unsafe オプションを使用した C# を使用すると、ポインターの隅々まで、手動のメモリ操作、命令、関数へのポインターなどにアクセスできます。
CPU の詳細を知らなくても、何かが欠けているわけではありません。
しかし、プログラムのパフォーマンスを本当に絞り出したい場合は、内部で何が行われているかを知ることに真の価値があり、プログラムがそれに値する場合は CPU/アセンブリ言語を学びます。
基礎となるアーキテクチャを理解することは、どのプログラマーにも役立つと思います。
最近の CPU は非常に複雑であるため、低レベルから作業することが良い考えかどうかはわかりません。Visual Basic を学び、次に Java を学びました。パフォーマンス クリティカルなコードを記述します。
高水準言語は、私たちが取り組んでいるシステムの低水準アーキテクチャから私たちを抽象化することを目的としています。これは、アーキテクチャ情報を無視する必要があるという意味ではありませんが、この情報の価値が低下していることを意味します。アーキテクチャ固有の知識は、実際にさまざまな方法でシステムを活用するのに役立ちますが、通常、これらの方法には、高級言語が提供する抽象化をバイパスすることが含まれます。これが良いことであるかどうかにかかわらず、私はあなたに任せます。
私は Basic でプログラミングを始めましたが (紙テープで!)、初期のキャリアで最高の経験の 1 つは組み込みシステムで働き、C およびアセンブリ言語プログラムを作成し、多くの場合クロスコンパイルを行ったことです。ハードウェアが何をするか、高水準言語が CPU にどのようにマッピングされるかなどを知ることは非常に役立ちます。ハードウェアをある程度理解していれば、ポインター、ポインター演算、データ構造のアライメント、符号拡張、さらにはソフトウェアのパフォーマンスやオペレーティング システムの動作を理解するのに役立ちます。
これは、答えがない質問の 1 つです。
実際には、いいえ、非常に具体的なことをしている場合を除いて、それはあまり役に立ちません (その場合は、より具体的な質問をする必要があります)。
理論的には、これは反対するすべての人が使用する議論です。はい、知っておくことは常に良いことです(...ほとんどすべて)... 1と0だけでプログラミングすることになるまで:)
最低レベルから始めた場合、おそらくこの「高」レベルに到達することはなかったでしょう。これがまさに、「高レベル」言語が最初に作成された理由です。
「CPU レベルから始めて、そこから教えれば、高レベルでの操作方法をより簡単に理解できるようになるかもしれません。」
間違い。
私がプログラミングを始めたのは 70 年代で、Fortran (または Jovial) かアセンブラーかを選択するため、ハードウェアがどのように機能するかを絶対に知らなければなりませんでした。
今、私は Java と Python を使用しています。まあ、まったくわかりません。私は、Dell ラップトップ、MacBook、iMac、および特定できないサーバーを持っています。
これらには、Intel または PowerPC プロセッサが搭載されている可能性があります。あるいは、サーバーは 64 ビットだと思いますが、どの種類かはわかりません。
一部のプロセッサについて多くの (本当に多くの) 知識を持っていても役に立ちませんでした。最新のプロセッサについて何も知らなくても問題ありません。
ソフトウェアは知識を取り込みます。ハードウェアの特定の部分は、ソフトウェアによって取得された知識とはほとんど関係がありません。
CPU 設計自体を理解することよりも重要なのは、最新の言語の下にある抽象化の「12 層ケーキ」を理解することです。そういうわけで、Nisan と Schocken による The Elements of Computing Systemsは私のお気に入りのプログラミング本です。「NAND から Tetris までの 12 ステップ」を実行し、チップ レベル、ALU レベル、CPU レベル、マシン コード レベルなどで「契約を守っている」ことを確認するためのユニット テストを行います。
カプセル化が重要であると言うのは 1 つのことです。これらの 12 層の間のカプセル化がなければ、このビジネスがいかに不可能であるかを理解することは、まったく別のことです。この本は、人間の脳が特定の複雑さを超えるともはや効果的ではなく、カプセル化が抽象的なタスクを管理するために使用する主要なツールであることを教えてくれます。論理回路から CPU を構築することでコンピューター ゲームを構築するプロセスは、複雑さと通信の間の負の関係、およびレイヤー間の明確な公的契約の最重要性について考えるようになったため、私のプログラミング方法を変えました。