彼らはどのようにこれを達成しますか?
多くの場合、10倍の生産性は10倍の能力または10倍の知識に起因すると考えられています。 そうは思いません 能力や知識は役に立たないとは言いたくありません。 しかし、長年にわたり、ここで最も重要なことは10倍の明瞭度であることに気づきました。 コツは、ひどい仕事を常に避けることです。
そして、それによって私は「知的に不満」というわけではありません。 お粗末な仕事の定義は、その結果がトイレに直接行くことです。
私自身は、特に経験が浅くて素朴なときは、お粗末な仕事をたくさんやり直しました。 (経験の大きな利点の1つは、人がだまされにくくなることです-これは、学校の記憶からの蒸発を補う以上のものです)。
私はあなたにハードワークの良い例、開発をしてトイレに直行することを与えます。10年前の不動点での私の冒険です。
「固定小数点演算」とは何ですか? 教えます これは、整数を処理するが、分数のふりをして、整数xが実際にはNの値に対して実際にはx / 2 ^ Nであると仮定した場合です。
2つの数値を追加するには、x + yを計算するだけです。 乗算には、x * y >> Nが必要です。なぜなら、ちょうどx * y-x * y / 2 ^ 2Nになるからですよね? また、このゴミがオーバーフローしないように注意する必要があります。1つの式で異なるNを処理するなどです。
その後、90年代初頭に、私たちの会社で開発されたプロセッサにプログラムを移植しました。 浮動小数点のハードウェアユニットは彼にとっては計画されていませんでした-「私たちはすべてを固定小数点で行います」。
ここに私の当時の出来事の一部があります:
- InteliFixed <N>と呼ばれるC ++テンプレートは、急いで作成する準備ができていました(まだ存在しますが、私はだまされていません)。 私はそれを作るために多くの仕事をしました、えーと...スローハンドに平手打ちします(ファストハンドの反対ですか?)。 たとえば、さまざまな型の2つの固定小数点数を受け取ったときに演算子+可換にする必要がありました(結果の型はどうなりますか?)。 64ビットの中間乗算をインラインで実行するひどいインラインアセンブラコードを作成します。 などなど
- 上司は、 2つのバージョンのコードを保持するように指示しました。1つは浮動小数点を使用し、アルゴリズムの高貴な開発者向けで、もう1つは固定コードを使用します。 したがって、これらのバージョンを手動で同期しました。
- また、ボスは、コードの一部を浮動小数点で実行し、一部ではなく 、精度の損失のエラーを見つける方法を考え出すように命じました。 したがって、2つのバージョンを1つに自動的にマージするC ++ヒューリスティックパーサーを作成しました。 彼は「フローティング」バージョンからいくつかの機能を、「固定」バージョンから他の機能を取り、ヘッダーなどの特別なファイルからそれらを選択しました。
もちろん、これらのマージされたがらくたはすべて開始されず、コンパイルさえされませんでしたね? そのため、マクロを作成しました。ベクター<float>&を渡さず、関数にREFERENCE(ベクター<float>)を渡して、ベクター<InteliFixed>(内部のコード)の実行をサポートするひどいコードを書きました。関数はそれをベクトル<float>に変換しました)。 - そして、このすべてのメタプログラミングに加えて、もちろんプログラミング自体がありました。 たとえば、5x5連立方程式を解いて、ノイズの多いデータ系列の多項式を選択し、すべて固定小数点を使用します。 正規化を伴う不気味なトリックを使用して動作させることができ、アセンブラーコードは96ビットの精度を使用しました。 私のコードは、正規化されていない単精度の浮動小数点コードよりもうまく機能しました! わあ!
何ヶ月もの間、私は完全な力で働いて、複雑でデバッグされたコードを生成しました-すべてはいつものように。
そして、ここに私が本当にする必要があるものがあります:
- この臭いチップの浮動小数点で臭いブロックを詰め込むように当局を説得するために。 これにはそれほど多くのシリコンの平方ミリメートルは必要ありません-私はいくつを計算することを主張しなければなりませんでした(ハードウェアFPUは次のプロセッサバージョンで追加されました)。
- これがうまくいかない場合は、回路シミュレータに行き、浮動小数点をエミュレートするコストを測定し、 それが許容できるコードの場所に適用しなければなりませんでした(徐々にしました)。
- 望みどおりに2つのバージョンを同期することは不可能であることを上司に伝えることは不可能です-彼らはさらに分岐し、最終的には、悪魔自身の助けを借りても、結果のコードをマージして実行することはできません(もちろん、これが最終的な方法です)。
なぜこの壮大なものはすべて、何ヶ月ものお粗末な仕事で退化したのですか? 何が起こっているのかわからなかったからです。 なぜなら、あなたが上司と議論することができるとは知らなかったからです。 作品は創造的で興味深いものだったからです。 すぐにトイレに行きました。
これらの10倍の人々、つまり非常に生産的であることを誰もが知っている人々を「管理」するのが最も難しいことは、彼らにタスクを引き継ぐよう説得することです。 (他のすべてはすでにはるかに簡単です-彼ら自身はどれくらい知っています;彼らが何かを引き受けた場合、それは行われます)。
あなたは完全に異なるものを期待していました、それを認めますか? 生産性が高い場合、何を心配する必要がありますか? あなたは速く働きます。 あなたを待っている最悪のことは、結果として何も出てこないということです-そして、あなたはすぐに何か他のものをするでしょう? つまり、選択が遅く、生産性があまり高くない人たちです。彼らは遅く、新しいものに切り替える能力が低いのですよね?
しかし、これは単なる錯覚です。生産性の高い人々はそれほど速く働かない-10倍速くはありません。 彼らが10倍速いように見える理由は、彼らがやったことのほとんどが捨てられないためです-他の人が行う仕事の山とは異なります。
また、生産性の問題は考慮されません。 あなたはその人を「Xを作った男」とみなします。Xの有用性はすべての人に知られています。 何かがこれのせいだったとしても-マネージャー、時間の不足、その他何でも。
有名な例を挙げると、CとUnixでケントンプソンを知っていますが、実際にはプラン9ではなく、Goではわかりません。 これまでの反対-GoはUnixを作った人たちの発案であるという理由だけであなたの注目を集めました。 LinuxはUnixのクローンですが、Geetは成功した製品のクローンであり、時間どおりに登場したため成功しました。
最初に見るのは、オリジナリティではなく、書くのがどれほど難しいか、または特定の基準に対してこのものがどれほど優れているかということです。
原則として、10倍のプログラマーは、決して使用されないものに関与しないように、実際の戦争を手配します。
これらの優秀な人の1人が、私が今終えたばかりのチェックスレッドについて、「誰かがこれを使用していますか?」と同じブランドの皮肉を込めて一度尋ねました。 私は知らないと言った。 誰かがハッカーニュースのコメントに書いて、彼らが試してみるかもしれないと書いた。
これは素晴らしいことです。 その助けを借りて、マルチスレッドプログラムのすべてのエラーを見つけることができます。 しかし、これはpthreadの代替ではありません。新しいインターフェイスを使用してコードを記述する必要があります。すでに使用しているインターフェイスではなく、優れたシンプルなインターフェイスです。 そのため、私のライブラリはほとんど関心がないでしょう。 Helgrindとスレッドサニタイザーには多数の誤検出がありますが、少なくとも人々が広く使用しているインターフェイスで動作します。
なぜこれを行うのでしょうか? 最初のバージョンを書くのに1日しかかからなかったので(並列ネストループなどを開始することに決めていなかったので)、ブログで自分のプログラムについて書いたら(今何をしているのか) ) 昔ながらの並列共有メモリで実際にエラーを追跡する方法を説明した投稿をいくつか書いた場合、CコードはRust、Go、またはErlangよりも簡単です。おそらく人々は注意を払うでしょう。
しかし、私が個人的に知っている10の群衆の中で失敗する可能性が多すぎます-あなたも試してはいけません。 たとえ自宅でcheckedthreadsのようなものを使用しても、非常に成功しています。 実際、私はこの非常に内部的なバージョンに多くの作業を入れた男から皮肉な質問を聞いた-私たちのプログラムが使用される可能性が非常に高いからです。
ほら 失敗する可能性のあることを行わないことは、パフォーマンスがどこにあるかです。
取り組む価値のあるものを選択するには? 考慮すべき多くのことがあります:
- すでに利用可能な代替手段はありますか? 彼女はどれほど悪いですか? 寛容な場合、自分で何もしません-良いことは改善するのが難しく、この改善が新しいバージョンに移行する価値があることを全員に納得させるのはさらに困難です
- このことはどれほど重要ですか? それがなければ、何も機能しませんか、それとも誰も気付かない小さなことですか?
- ユーザーが利益を得るにはどれくらいの作業が必要ですか? 既存のコードまたはデータで既に機能していますか? 人々は何か新しいことを学ばなければならないのか、それとも以前のように働くことができるのか?
- 少なくともそれを広めるために、このことについて何人の人が学ぶべきでしょうか? 古いコードに付属しているため、ユーザーは何も知らずにコードを実行しますか、それとも何かをインストールする必要がありますか? (関数を自動的に取得し、それを実際に研究することは、何か新しいものをインストールしてすぐに忘れてしまうよりも良い場合が多いです。最終的にExcelで新しい関数を学習した人の数と、バックグラウンドで)。
- どのくらいのコードが良いのでしょうか? サウンドをmpeg形式に圧縮する小さなカーネルのパルスの損失を最適化することは、1.2倍の加速を達成するために100万行のコードを表示するよりも便利に見えます(ただし、後者のオプションは単独で役立つ場合がありますが、通常は10倍のプログラマが必要です) 、1人の「テンフォールド」プログラマだけではありません)。
- 新しい機会はそれ自体を保護できますか? ユーザーが何か間違った(または「間違った」)場合、それは静かに役に立たなくなり(アナライザーがプログラムを理解できなくなったときの静的コード分析など)、エラーが修正されるまで動作を停止します(範囲外配列のチェックなど) )?
- ...
このリストは簡単に続けることができます。 彼の主なアイデアは、私がこのことを終了し、それが実際に使用される可能性は何ですか? 同じ考え方が、すべての関数、サブ関数、コード行に再帰的に適用されます。それらのおかげで全体が役立つのでしょうか? そして、私はより多くの利益をもたらす他のものに時間を費やしませんか?
もちろん、さらに複雑です。 いくつかの有用なものは、さまざまな理由で他のものよりも高く評価されています。 ここで、リチャードストールマンが登場し、GNUがほとんどのユーザープログラムを作成したため、Linuxを「GNU / Linux」と呼ぶことを要求しています。 そして、私は「Gnu-Linux」システムと呼ぶつもりはありませんが、残念ながら、その主張は独自の真実を持っています。つまり、残念ながら、いくつかの難しい重要な作業は他の難しい重要な作業ほど目立ちません。
しかし、正義は別のトピックです。 結局、10倍のパフォーマンスで10倍の補償が得られることはほとんどありません。
したがって、「チート」する多くの理由はなく、あなたよりも生産的だと思われます。 人々が生産的である主な理由は、彼らがお尻を縫い、忘れられないということであり、具体的な利益ではないということです。
私が言いたいことは次のとおりです。より多くのことをするために、あなたはより速く成功するためにそれほど必要ではありませんが(これは傷つきません)、 失敗することは少なくなります。 そして、すべての失敗が知識や経験の不足によって引き起こされるわけではありません。 それらのほとんどは、プログラムを使用することがまだ不可能な段階でプログラムが放棄された場合、または最初から誰も使用しなかったために発生します。
したがって、私は、トイレ用に多くのコードを書いた人として、パフォーマンスを達成するために、 仕事が不足するほど仕事をする必要はなく、最終的にゴミに捨てられることをしないことが必要だと思います。
投稿者:Joseph Kreinin
オリジナル: www.yosefk.com/blog/10x-more-selective.html