[過去ログ] Go language part 5 (1002レス)
前次1-
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
21
(1): デフォルトの名無しさん [sage] 2022/02/28(月) 00:19:43.12 ID:BEDnUIJv(1/3) AAS
>>16
16(1): デフォルトの名無しさん [sage] 2022/02/27(日) 21:18:41.64 ID:Xl3wWN+O(2/2) AAS
>>15
Goと同じくtry-catchの無いRustはメソッドチェーンが基本の言語だぜ
関数の返り値が基本的にenumとなってエラーも正常値もメソッドチェーンで処理できるようになってる
以下9章だけは読んだ。
外部リンク[html]:doc.rust-jp.rs

俺はこれで全く問題ないけども、try-catch派は多分文句を言うような気はする。
あと、これは型をResultで統一すればどの言語でも出来るので、言語と言うよりはフレームワークの設計なのだろう。
(フレームワークを跨いでも統一してる方がいいから、言語としてこれだ!というのは意味はあるが)

ただ、エラー処理って方式が統一されてる事が重要だから、今更ではある。
そんな事よりGoはRustのasyncをパクるべきだろう。
コルーチンみたいな名前で実はスレッドではないか!という批判が無くなる。
実は当初goroutineと名付けた時に欲しかったのは、これだったんじゃね?とも思う。
yieldさえあればあっさり出来るのだろうけど。(無くても無理矢理やれば出来るが)
つか、無い理由は何なんですかねこれ?
35
(1): デフォルトの名無しさん [sage] 2022/02/28(月) 21:21:31.32 ID:BEDnUIJv(2/3) AAS
>>23
23(1): デフォルトの名無しさん [sage] 2022/02/28(月) 00:35:47.82 ID:EeqSDih1(1/3) AAS
>>17 >18
むしろ前スレ957のベンチ(元記事)では、

"In particular, 10k threads with default stack sizes need about 40mb of page tables to map virtual memory."

と訂正しているのだから、前スレ962の計算で40MB足してるのはおかしくない。
ただ、>>4で再び「957のベンチでは40MB越えないとおかしくて、矛盾してる」と言ってるのが、普通に考えるとRSS対象なので、スレッド数を10kから1kにした俺版でも前スレ1000のC++版との対比する意味もあり、改めてgo版の結果を同じ条件で出した(>>6)だけ。
結論は同様にRSSは4MBを超えないので、仮想メモリ側にあるという元記事の主張で正しいようにも見える。
しかし、go処理系が不明な元記事と違い、自分でやっていれば実際バージョンは分かるわけで、そこが分かればスタックサイズはソースを見れば一目瞭然ということで経緯と一緒に調べたのが、>>12で結論としては2Kだったということ。
すると元記事の推測と自分の計測結果には矛盾があり、2KBが仮想メモリにあるかどうかを明確にする必要が出たため、>>14で/procに頼った。
結論は仮想メモリ(swap)使ってないよって話だったので、少なくとも俺の環境では元記事とは違いRSSでいいという結論が出て、>12の結論とも整合が取れた。

別にdistro標準(ubuntu 20.04)のgo処理系を使っているので、ソースを引っ張ってくれば簡単に1KBに変更は出来るか確認出来ると思うけど、面倒なのでそこまではしない。
いや、元記事もそこはちょっと間違ってる。
とはいえ本質は「RSSで全部計上されてるか?」なので大筋は問題ないが。

RSSは「ユーザープロセス空間で、メモリ上に配置されてる物」なので、元記事の通り、スワップされてれば計上されないが、
そもそもこの計測方法では普通はスワップされない。
ただ、考慮してるのは"Thread bookkeeping"であって、
kernel(OS)がこれに使うメモリがRSSに計上されてないから問題だ、というのはあってる。
だから俺はそれを足してる。

Goでは、実はこの部分も売りにしてて、以下は8の2つ目だが
> 外部リンク:dave.cheney.net
> The switch between goroutines only happens at well defined points, when an explicit call is made to the Go runtime scheduler.
> The compiler knows the registers which are in use and saves them automatically.
むやみにプリエンプトせず、スイッチングポイントを考えて、必要ないレジスタは待避してない。
考えられるのは
・そもそもセグメントレジスタなんて普通は使わないから待避する必要がない。(レガシー)
・関数の途中でプリエンプトせず、関数呼び出し単位でスイッチなら、
呼び出し規約上の破壊レジスタ(a,b,c,d)は待避する必要がない。
・そのgoroutineの処理にSSE命令が存在しなければ、SSE系レジスタを待避する必要がない。FPU(x87)も同様。
とかになる。
(なおこれを突き詰めたらRustの「コルーチンのyieldでスイッチすれば、スタックも要らん」になる)
そして現実的に多くの場合SSE系命令は不要で、必要待避領域は多分半分以下にはなるので、(面倒だから数えてないが)
Goは半分以下にする努力してるのにRSSだと計上され、OS任せだと丸々必要なのにRSSには計上されないので、
当然の如く突っ込まれる事になる。
(その他細かいフラグ類は沢山あるだろうけど、多くはbit単位であり容量としてはゴミなので無視)

だから最小フットプリントなら1/3程度で、
あまり余計なことしなければスイッチングコストも1/3程度としていいのではないかと。
逆に言えば、threadよりも3倍程度のgoroutineで済むのなら、速くてコードも綺麗だが、
それ以上なら遅くなるという事。
36: デフォルトの名無しさん [sage] 2022/02/28(月) 21:59:11.85 ID:BEDnUIJv(3/3) AAS
>>27,28
27(3): デフォルトの名無しさん [sage] 2022/02/28(月) 14:52:59.85 ID:xNWA4laA(1/2) AAS
このasyncおじさんは何も分かってないと思う・・・
nodeでasync/awaitが通るのは、シングルスレッドですべてのメモリーが一緒のためで、Goのようにgoroutineで実際に
割り当てられているCPUやスレッドが分からないようにあえてしている言語で、asyncなんて導入するわけない。
async/awaitがある言語でそれがThreadを混ぜ込める言語もあるが、それだってI/Oをブロックしている処理の終わりに
ただ同じスレッドを再割り当てするだけ。スレッド境界を越えてメモリーコピーあるいは同期なんてしてたら破綻する
async/awaitのもとになるような、多くのスクリプト言語でyield、つまりジェネレータの重要なユースケースは、I/Oブロックの
待ちで違う処理を行うことだが、それはI/Oバウンドな待ちでしか処理が切り替わらないことを意味する。
28(2): デフォルトの名無しさん [sage] 2022/02/28(月) 15:07:48.45 ID:xNWA4laA(2/2) AAS
async/await,そしてyieldが唯一優れているのは、Goでいうchannelのclose処理が要らないことだけ。

他は全部劣っているし、CPUバウンドでは切り替わらないし、async/awaitなんていうキーワードがプログラミングがしやすいか
といえば全然そんなことは無く、async/awaitで書かれたコードと、完全同期の一直線で進むプログラミングでは、互換性に
乏しいライブラリばかりができる。async前提で作られたコードは同期プログラミングでは使えなかったり、同期プログラミングで
作られたライブラリは処理がI/O待ちになっても、asyncが入っていないため非同期では効率が劣る。
決定的には、並列性が大きく劣っている事は言うまでもない。
もちろんこれは速度などという効率の指標ではなく、理論上はCPUコア数=スレッド数で、他はすべて非同期にしたほうが
速いのは、何も考えずとも当たり前。(無駄なコンテキストスイッチや同期処理が発生しないから)

「当初欲しかったのはこれじゃね?」なんていう超ド素人の勝手な想像と思い込み、調べもしない無知でこんなところで
ダベっていてもまったく意味ない。
Go言語の作者の一人であるRob Pike氏が「OSスレッドではなく、ユーザー空間スレッド」「メモリ使用量がOSスレッドに
対して、500倍ほど有利」「OSコンテキストスイッチよりも有利」といい、Cの作者として有名な、Kenneth Thompsonが
「C++が嫌いだということで意気投合」「いかなる理由があっても言語にゴミを入れません」と語っているように
I/O非同期なんていう半端な偽物は、眼中にない中で、まさしくasync/awaitは1つの利点だけの無用な長物であり
プログラミングを複雑にするだけで、つい最近まで総称型さえも、強烈に拒んでいた保守的で長く使えるよう言語仕様を
守り続ける言語に入るわけない。
そんなにやりたかったらお前がforkしてやれ、じゃなきゃGithubでIssueでも投下してこい。それすら出来ないなら
お前は不当に他言語を卑下してる卑怯者だぜ。どうせボコボコにされる
どこから突っ込めば状態なので、最初の部分だけ。

> nodeでasync/awaitが通るのは、シングルスレッドですべてのメモリーが一緒のためで、
これは多分プロセスとスレッドの区別が出来てない。
プロセスは別空間だがスレッドは同一空間で、逆に言えばその程度の違いしかないが。
> e.g. Linux doesn’t distinguish between threads and processes and both are called tasks.
> 外部リンク:codeburst.io

> Goのようにgoroutineで実際に割り当てられているCPUやスレッドが分からないようにあえてしている言語で
一般的に非同期の場合はどのCPUにどの順番で処理されても動くように組む必要があり、
実際にC#でもそう。
JSもそう。(ただしJSのプログラミングモデルからは見えない)
この発言は上記の勘違い、(とは言っても普通の勘違いとは逆で)
Goはgoroutineがそれぞれ「別空間」で動いていると勘違いしてるからだと思うのだが、それはない。
重ならないようにコンパイラが割り当ててくれてるだけで、同一空間だ。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.148s*