「C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな」
「うだうだ言ってないで仕事で必要なのをやればいいんだよ、趣味なら好きなのやればいい」
っていう雑談スレ。
結局C++とRustってどっちが良いの? 4traits
https://mevius.5ch.net/test/read.cgi/tech/1686046386/
関連スレ(マ板): Google&MS「バグの70%はC/C++。Rustにする」
https://medaka.5ch.net/test/read.cgi/prog/1619943288/
探検
結局C++とRustってどっちが良いの? 5traits
■ このスレッドは過去ログ倉庫に格納されています
2023/06/30(金) 21:56:35.52ID:PDIJ4aZy
110デフォルトの名無しさん
2023/07/03(月) 09:32:31.64ID:XuaWdgM7 確かに WideCharToMultiByte/MultiByteToWideChar は毎回
↓
容量確認で1回目呼び出し
↓
確保して
↓
容量指定して2回目呼び出し
↓
面倒だと思ってた
↓
容量確認で1回目呼び出し
↓
確保して
↓
容量指定して2回目呼び出し
↓
面倒だと思ってた
111デフォルトの名無しさん
2023/07/03(月) 09:54:04.75ID:gVPXZxAL 毎回書くからだろ、ライブラリ(コードスニペット)にしちゃえw
112デフォルトの名無しさん
2023/07/03(月) 10:05:14.03ID:kK4jJ7eL コンパイラが吐き出すコードなんて意図通りにならない
疑い深いなら細かくチェックしながらアセンブラで書くしかない
ループ内の重要な変数はレジスタを使っているか
無駄なコピーが無いか
ループ部分に無駄な関数呼びだしが無いか
実際のメモリに読み書きしやすい順序でデータが並んでいるか
最初に必要なメモリを一括でOSから取得しているか
最適な命令を使っているか
キャッシュ汚染が無いか
疑い深いなら細かくチェックしながらアセンブラで書くしかない
ループ内の重要な変数はレジスタを使っているか
無駄なコピーが無いか
ループ部分に無駄な関数呼びだしが無いか
実際のメモリに読み書きしやすい順序でデータが並んでいるか
最初に必要なメモリを一括でOSから取得しているか
最適な命令を使っているか
キャッシュ汚染が無いか
113デフォルトの名無しさん
2023/07/03(月) 10:10:50.88ID:gVPXZxAL アセンブラで書いてすら、意図通りにならないくらいに思っとけってばっちゃんが言ってた
(適当に分割して、複数パイプラインに流し込まれたりするから)
(適当に分割して、複数パイプラインに流し込まれたりするから)
114デフォルトの名無しさん
2023/07/03(月) 11:59:58.23ID:fwYpLKgv >>96
RVOだよなぁ
RVOだよなぁ
115デフォルトの名無しさん
2023/07/03(月) 16:06:04.98ID:+YxiNHjZ116デフォルトの名無しさん
2023/07/03(月) 16:10:20.37ID:+YxiNHjZ このようにC++は色々複雑すぎてもはや普通の人が理解できるものではなくなったので
素直にrust使おうよという振りなんだけどね
素直にrust使おうよという振りなんだけどね
117デフォルトの名無しさん
2023/07/03(月) 16:16:32.89ID:5E3kHz23 Rustだとどうなるの? ソースで例示プリーズ
118デフォルトの名無しさん
2023/07/03(月) 16:53:27.10ID:uVoNxoEf たとえば64bit二つ分を返すと
#[derive(Default)]
struct Foo { a: u64, b: u64, }
impl Foo {
fn new(a: u64) -> Self {
let mut foo = Foo::default();
foo.a = a;
println!("foo: 0x{:p}", &foo);
foo
}
}
fn main() {
let fff = Foo::new(123);
println!("fff: 0x{:p}", &fff);
}
レジスタ返しができる範囲なので両者のアドレスは異なる
foo: 0x0x7ffc3e73a6d8
fff: 0x0x7ffc3e73a740
一つ増やして64bit三つ分を返すと
struct Foo { a: u64, b: u64, c: u64, }
レジスタ返しではなくなり
いわゆるRVO (Return Value Optimization)
呼び出し元main()のスタックフレームに直接書き込むため両者のアドレスは同じになる
foo: 0x0x7ffc03863d78
fff: 0x0x7ffc03863d78
#[derive(Default)]
struct Foo { a: u64, b: u64, }
impl Foo {
fn new(a: u64) -> Self {
let mut foo = Foo::default();
foo.a = a;
println!("foo: 0x{:p}", &foo);
foo
}
}
fn main() {
let fff = Foo::new(123);
println!("fff: 0x{:p}", &fff);
}
レジスタ返しができる範囲なので両者のアドレスは異なる
foo: 0x0x7ffc3e73a6d8
fff: 0x0x7ffc3e73a740
一つ増やして64bit三つ分を返すと
struct Foo { a: u64, b: u64, c: u64, }
レジスタ返しではなくなり
いわゆるRVO (Return Value Optimization)
呼び出し元main()のスタックフレームに直接書き込むため両者のアドレスは同じになる
foo: 0x0x7ffc03863d78
fff: 0x0x7ffc03863d78
119デフォルトの名無しさん
2023/07/03(月) 17:12:42.36ID:uVoNxoEf 前者のアドレスが異なる場合というのは
レジスタ上だけで済むところを敢えてアドレス表示させているため
実際にはスタックを使わずレジスタのみの利用に成りうることを意味してることに注意
レジスタ上だけで済むところを敢えてアドレス表示させているため
実際にはスタックを使わずレジスタのみの利用に成りうることを意味してることに注意
120デフォルトの名無しさん
2023/07/03(月) 18:59:43.08ID:MgkFcxqO なるほどrustは呼び出し元スタックに直接値返せるのね
コレはC++でできるんですか?
コレはC++でできるんですか?
121デフォルトの名無しさん
2023/07/03(月) 20:50:38.98ID:5E3kHz23 $ cat test.cpp
#include <iostream>
#include <cstdint>
using namespace std;
struct Foo {
uint64_t a;
uint64_t b;
static Foo new_ (uint64_t a) {
Foo foo; foo.a = a;
cout << "foo: " << &foo << '\n';
return foo;
}
};
int main () {
auto fff {Foo::new_ (123)};
cout << "foo: " << &fff << '\n';
return 0;
}
$ g++ -O0 -std=c++20 -o test test.cpp
$ ./test
foo: 0x7fff0bbf3540
foo: 0x7fff0bbf3560
$ g++ -O3 -std=c++20 -o test test.cpp
$ ./test
foo: 0x7ffed05f53a0
foo: 0x7ffed05f53a0
#include <iostream>
#include <cstdint>
using namespace std;
struct Foo {
uint64_t a;
uint64_t b;
static Foo new_ (uint64_t a) {
Foo foo; foo.a = a;
cout << "foo: " << &foo << '\n';
return foo;
}
};
int main () {
auto fff {Foo::new_ (123)};
cout << "foo: " << &fff << '\n';
return 0;
}
$ g++ -O0 -std=c++20 -o test test.cpp
$ ./test
foo: 0x7fff0bbf3540
foo: 0x7fff0bbf3560
$ g++ -O3 -std=c++20 -o test test.cpp
$ ./test
foo: 0x7ffed05f53a0
foo: 0x7ffed05f53a0
122デフォルトの名無しさん
2023/07/03(月) 21:12:04.60ID:MgkFcxqO >>121
それは呼び出し側のスタックですか?
それは呼び出し側のスタックですか?
123デフォルトの名無しさん
2023/07/03(月) 21:12:23.79ID:5E3kHz23 NRVOなのでいつも効くとは限らない?
124デフォルトの名無しさん
2023/07/03(月) 21:15:14.72ID:5E3kHz23 >>122
0x7fff0bbf3560と0x7ffed05f53a0は呼び出し側のスタックなのでは?
0x7fff0bbf3560と0x7ffed05f53a0は呼び出し側のスタックなのでは?
125デフォルトの名無しさん
2023/07/03(月) 22:09:08.78ID:+q7z5VN1 たったそれだけのことを
ヒープから確保してガベージコレクションで解放する重い遅いプログラミング言語がほとんどの中
C++とRustが優秀すぎるハイレベルな戦い
ヒープから確保してガベージコレクションで解放する重い遅いプログラミング言語がほとんどの中
C++とRustが優秀すぎるハイレベルな戦い
126デフォルトの名無しさん
2023/07/03(月) 23:25:23.71ID:MgkFcxqO127デフォルトの名無しさん
2023/07/03(月) 23:28:41.59ID:MgkFcxqO あ、いや、今ググったらC++でもRVO実現してるみたいですね
失礼しました
しかし本当にそのアドレスの数値が一致していることだけでRVOが効いてる事の証明にはならないとは思います
失礼しました
しかし本当にそのアドレスの数値が一致していることだけでRVOが効いてる事の証明にはならないとは思います
128デフォルトの名無しさん
2023/07/03(月) 23:31:27.59ID:MgkFcxqO あ、よくよく読んだら「RVOとは戻り値返す時にコピーしない技術のこと」であって「呼び出し側のスタックを利用するかどうか」は別問題のようですね
まぁだからC++もRustも両方ヒープ使ってRVOしてるだけかもしれない
まぁだからC++もRustも両方ヒープ使ってRVOしてるだけかもしれない
129デフォルトの名無しさん
2023/07/03(月) 23:46:31.39ID:uVoNxoEf ヒープが勝手に使われることはない
ヒープとスタックは空間を通常分けてありアドレス値も見ればわかるくらい異なる値を使っている
単純なローカル変数のアドレス値との比較からスタックのアドレス値かどうかすぐわかる
ヒープとスタックは空間を通常分けてありアドレス値も見ればわかるくらい異なる値を使っている
単純なローカル変数のアドレス値との比較からスタックのアドレス値かどうかすぐわかる
130デフォルトの名無しさん
2023/07/03(月) 23:47:11.84ID:5E3kHz23 >>128
根拠までは示せんが
俺はC/C++とやってきて
関数にnewを直接/間接に呼び出さなずにインスタンスを作れば
スタックに確保されるという認識だな
なのでRVO効いてれば呼び出し側のスタックに作成されるという風に考えている
根拠までは示せんが
俺はC/C++とやってきて
関数にnewを直接/間接に呼び出さなずにインスタンスを作れば
スタックに確保されるという認識だな
なのでRVO効いてれば呼び出し側のスタックに作成されるという風に考えている
131デフォルトの名無しさん
2023/07/04(火) 00:03:31.80ID:axzJnblJ Rustはリターンの場合は多分コピーしてると思いますよ。なぜならサイズの大きい配列の計算において返り値ありときとポインタから直接いじる返り値なしの場合で返り値なしの方が圧倒的に実行速度が速かったから。
132デフォルトの名無しさん
2023/07/04(火) 00:16:23.10ID:Z5BWnaiC 推測するな
逆アセンブリ読め
逆アセンブリ読め
133デフォルトの名無しさん
2023/07/04(火) 00:36:27.02ID:+0TfLuMN134デフォルトの名無しさん
2023/07/04(火) 00:36:48.56ID:zEsCcd3F135デフォルトの名無しさん
2023/07/04(火) 01:08:19.71ID:+0TfLuMN Rustのコンパイラがどういう方法でRVOを実現してるかは多分実装依存で「可能な限りやるようにしろ、プログラマはRVOが働いてくれると期待していい」くらいまでは書いてあるんかもしれないですね
実装としては予想ですけど
・関数のスコープ内でローカルに作られた変数(左辺値?)は原則スタック領域に確保されて関数の処理終了時点で全て解放される
・しかし関数の戻り値として呼び出し側の変数にバインドされて生存期間が伸びた変数は消去されず呼び出し側スタックに残す
・もちろん>>103のような例でコンパイル時点でobject a, object bのどちらを残すか決定できないなら両方残して返り値として使われなかった方のメモリは穴として諦める、どのみちその“呼び出し側の関数”が終了する時点で解放される穴なので諦める
みたいな実装なんでしようかねぇ?
私アセンブラ読めないので確かめられませんけど
実装としては予想ですけど
・関数のスコープ内でローカルに作られた変数(左辺値?)は原則スタック領域に確保されて関数の処理終了時点で全て解放される
・しかし関数の戻り値として呼び出し側の変数にバインドされて生存期間が伸びた変数は消去されず呼び出し側スタックに残す
・もちろん>>103のような例でコンパイル時点でobject a, object bのどちらを残すか決定できないなら両方残して返り値として使われなかった方のメモリは穴として諦める、どのみちその“呼び出し側の関数”が終了する時点で解放される穴なので諦める
みたいな実装なんでしようかねぇ?
私アセンブラ読めないので確かめられませんけど
136デフォルトの名無しさん
2023/07/04(火) 01:50:19.31ID:T/PNhAd4137デフォルトの名無しさん
2023/07/04(火) 02:24:25.89ID:H9LDX83D 関数がインライン展開されたら関数間の変数のコピーは省略される
レジスタ変数は参照を取得出来ない
逆にいうと参照を取得したらレジスタではなくメモリ変数(非レジスタ変数)になる
Rustではよく所有権の借用のための参照取得をするけれどそれが
C++ほど最適化されるのでしょうか
レジスタ変数は参照を取得出来ない
逆にいうと参照を取得したらレジスタではなくメモリ変数(非レジスタ変数)になる
Rustではよく所有権の借用のための参照取得をするけれどそれが
C++ほど最適化されるのでしょうか
138デフォルトの名無しさん
2023/07/04(火) 02:44:11.87ID:+0TfLuMN >>118
の追試
https://ideone.com/6g3Ne2
関数内で2つのFoo型を作ってどっちを返すかコンパイル時には分からない(はす)のコードで実現
fn whichFoo ()-> Foo {
let a = Foo::new(456);
let b = Foo::new(789);
if( true ){
a
}else{
b
}
}
この関数を2回呼んで返り値のアドレスと比較
結果びっくりした
a 456 foo: 0x0x7ffff3242cd0 // 1階目の1項目(返す方)
a 789 foo: 0x0x7ffff3242c98 // 1階目の2項目(捨てる方
fff: 0x0x7ffff3242cd0 // 返り値、1個目と一致
a 456 foo: 0x0x7ffff3242cb0 // 2階目の1項目(返す方)
a 789 foo: 0x0x7ffff3242c98 // 2階目の2項目(捨てる方
fff: 0x0x7ffff3242cb0 // 返り値、1個目と一致
で2回呼んで2回とも1個目のアドレスと一致でRVOが効いてる
のみならず1回目で捨てた方のアドレスが2回目のすてる方のアドレスとして再利用されてる
コレはどうやってんの?
全く予想外
の追試
https://ideone.com/6g3Ne2
関数内で2つのFoo型を作ってどっちを返すかコンパイル時には分からない(はす)のコードで実現
fn whichFoo ()-> Foo {
let a = Foo::new(456);
let b = Foo::new(789);
if( true ){
a
}else{
b
}
}
この関数を2回呼んで返り値のアドレスと比較
結果びっくりした
a 456 foo: 0x0x7ffff3242cd0 // 1階目の1項目(返す方)
a 789 foo: 0x0x7ffff3242c98 // 1階目の2項目(捨てる方
fff: 0x0x7ffff3242cd0 // 返り値、1個目と一致
a 456 foo: 0x0x7ffff3242cb0 // 2階目の1項目(返す方)
a 789 foo: 0x0x7ffff3242c98 // 2階目の2項目(捨てる方
fff: 0x0x7ffff3242cb0 // 返り値、1個目と一致
で2回呼んで2回とも1個目のアドレスと一致でRVOが効いてる
のみならず1回目で捨てた方のアドレスが2回目のすてる方のアドレスとして再利用されてる
コレはどうやってんの?
全く予想外
139デフォルトの名無しさん
2023/07/04(火) 02:53:28.80ID:ZPezMZV3 そんな気になるなら生成されたコード見たら?
140デフォルトの名無しさん
2023/07/04(火) 03:12:41.98ID:w64gVUS7141デフォルトの名無しさん
2023/07/04(火) 03:23:48.80ID:H9LDX83D >>140
thxです
thxです
142デフォルトの名無しさん
2023/07/04(火) 07:50:54.82ID:+0TfLuMN >>141
イヤそれをどうやってんのって話
オレが当然こういうimplementだろうと思ってたのはこう
whichFooが呼ばれてstackが割り当てられる(でもおそらくそのプロセスに割り当てられてるスタックのスタックポインタの上端もらってくるだけだと思うけど)
もらったstackに上から詰めてFoo型のaとbができる
普通に考えて上端から順にaのための領域、bのための領域
この2つは返り値として使用される可能性があるからmainのstackの下端のすぐ下に作ってはおくけどどちらが使われるかは不定
①呼び出し前(♪がsp)
[ 未使用域 ]♪| [mainのstack ]
②1回目呼び出し直後
[未使用域]♪[ b ][ a ]| [mainのstack ]
実行時に[a]が返される事が確定、bは破棄されて[a]の真下にspを戻してmainの再開から2回目呼び出されて同じく[a],[b]が作られる
③2回目呼び出し直後
[ 未使用域 ]♪[ a ]| mainのstack ]
④2回目の変数領域確保
[未使用域]♪[ b ][a'][ a ]| [mainのstack ]
⑤2回目の変数領域確保
[ 未使用域 ]♪[a'][ a ]| [mainのstack ]
となると予想したら違った
イヤそれをどうやってんのって話
オレが当然こういうimplementだろうと思ってたのはこう
whichFooが呼ばれてstackが割り当てられる(でもおそらくそのプロセスに割り当てられてるスタックのスタックポインタの上端もらってくるだけだと思うけど)
もらったstackに上から詰めてFoo型のaとbができる
普通に考えて上端から順にaのための領域、bのための領域
この2つは返り値として使用される可能性があるからmainのstackの下端のすぐ下に作ってはおくけどどちらが使われるかは不定
①呼び出し前(♪がsp)
[ 未使用域 ]♪| [mainのstack ]
②1回目呼び出し直後
[未使用域]♪[ b ][ a ]| [mainのstack ]
実行時に[a]が返される事が確定、bは破棄されて[a]の真下にspを戻してmainの再開から2回目呼び出されて同じく[a],[b]が作られる
③2回目呼び出し直後
[ 未使用域 ]♪[ a ]| mainのstack ]
④2回目の変数領域確保
[未使用域]♪[ b ][a'][ a ]| [mainのstack ]
⑤2回目の変数領域確保
[ 未使用域 ]♪[a'][ a ]| [mainのstack ]
となると予想したら違った
143デフォルトの名無しさん
2023/07/04(火) 07:51:01.03ID:+0TfLuMN 今のは運良く最初に確保したaの方が返り値として使われたので簡単に領域bが再利用できるけど、もちろん一般には分からない、なのでコンパイラのできることといえば返り値になるかもしれないbの領域はスタック上端に確保しておいてなるべくフラグメンテーションが起きても被害最小に止めるくらいかなと思ったら違った
(ちなみに残す方と捨てる方逆にしても結果は同じ)
確保されたアドレス見るにコンパイラは最初からaが返されるのを見越して[a]の領域だけをmain側のstackに割り当ててるように見える、1回目も2回目も、そして1回目終了時に回収されたbのためのエリアが再利用されてる
レジスタの場合と徹底的にに違うのはメモリの場合「空いてたら使う」を実現するには“未使用域を完全に把握して新しく領域を確保する時未使用域をなるべく活用する”がかなり難しい事
普通は使用してる下端と未使用の上端の境界にsp置いとくくらいが限界
「使用してるのは①〜②、③〜④、....」なんてできるはずない、できるハズないからフラグメンテーション問題が発生する
もちろんこの“できるはずない”事をやってれば実験結果みたいになって不思議ないんだけど流石に無理じゃないかと
(ちなみに残す方と捨てる方逆にしても結果は同じ)
確保されたアドレス見るにコンパイラは最初からaが返されるのを見越して[a]の領域だけをmain側のstackに割り当ててるように見える、1回目も2回目も、そして1回目終了時に回収されたbのためのエリアが再利用されてる
レジスタの場合と徹底的にに違うのはメモリの場合「空いてたら使う」を実現するには“未使用域を完全に把握して新しく領域を確保する時未使用域をなるべく活用する”がかなり難しい事
普通は使用してる下端と未使用の上端の境界にsp置いとくくらいが限界
「使用してるのは①〜②、③〜④、....」なんてできるはずない、できるハズないからフラグメンテーション問題が発生する
もちろんこの“できるはずない”事をやってれば実験結果みたいになって不思議ないんだけど流石に無理じゃないかと
144デフォルトの名無しさん
2023/07/04(火) 07:56:44.61ID:+0TfLuMN でも可能性はあるのかな
プロセス全体で共有されるヒープ全体の使用状況なんか全部管理できないけどローカルの関数に割り当てられたスタックなんてしれてるから使用域、未使用域全部管理してるのかな?
プロセス全体で共有されるヒープ全体の使用状況なんか全部管理できないけどローカルの関数に割り当てられたスタックなんてしれてるから使用域、未使用域全部管理してるのかな?
145デフォルトの名無しさん
2023/07/04(火) 09:22:16.43ID:X5jhzPkA Rustで標準的なチャート生成(グラフ描画)ツールは何ですか?
146デフォルトの名無しさん
2023/07/04(火) 10:49:51.72ID:0JerF0m8147デフォルトの名無しさん
2023/07/04(火) 11:02:31.68ID:XZOUnAWZ148デフォルトの名無しさん
2023/07/04(火) 11:18:09.81ID:XZOUnAWZ >>146
Rustもinline展開される
それとは独立にRustの基本動作として常にRVOが起きる
>>118のコードを
debug mode ← cargo run
release mode ← cargo run -r
の2種類で実行すると
➀debug modeでstruct Foo { a: u64, b: u64, }の場合
→ fooとffiは別アドレス
このdebug modeではinline最適化はされていない
レジスタ返しできる範囲であるため別アドレス
➁release modeでstruct Foo { a: u64, b: u64, }の場合
→ fooとffiは同じアドレス
これはrelease modeでinline最適化がされたため同じアドレスとなった
➂debug modeでstruct Foo { a: u64, b: u64, c: u64 }と大きいサイズの場合
→ fooとffiは同じアドレス
これは➀によりinline最適化はされていない
レジスタ返しできる範囲を超えてるためmain()スタックフレームに直接アクセスしている
Rustもinline展開される
それとは独立にRustの基本動作として常にRVOが起きる
>>118のコードを
debug mode ← cargo run
release mode ← cargo run -r
の2種類で実行すると
➀debug modeでstruct Foo { a: u64, b: u64, }の場合
→ fooとffiは別アドレス
このdebug modeではinline最適化はされていない
レジスタ返しできる範囲であるため別アドレス
➁release modeでstruct Foo { a: u64, b: u64, }の場合
→ fooとffiは同じアドレス
これはrelease modeでinline最適化がされたため同じアドレスとなった
➂debug modeでstruct Foo { a: u64, b: u64, c: u64 }と大きいサイズの場合
→ fooとffiは同じアドレス
これは➀によりinline最適化はされていない
レジスタ返しできる範囲を超えてるためmain()スタックフレームに直接アクセスしている
149デフォルトの名無しさん
2023/07/04(火) 11:53:43.89ID:0JerF0m8 >>121を-fno-inlineをつけてビルドしてみた
$ g++ -O3 -fno-inline -std=c++20 -o test test.cpp
$ ./test
foo: 0x7fffb2b5ee40
fff: 0x7fffb2b5ee40
-fno-inlineでインライン展開されていないとするならRVOが効いている
$ g++ -O3 -fno-inline -std=c++20 -o test test.cpp
$ ./test
foo: 0x7fffb2b5ee40
fff: 0x7fffb2b5ee40
-fno-inlineでインライン展開されていないとするならRVOが効いている
150デフォルトの名無しさん
2023/07/04(火) 13:35:05.06ID:sBWOwVL+ global optimizationがかかったら、どっちにしても、いいようになるのかもしれない
いいようになってくれと思って書くのがいい これはC++もRustも同様
いいようになってくれと思って書くのがいい これはC++もRustも同様
151デフォルトの名無しさん
2023/07/04(火) 15:10:09.42ID:X5jhzPkA Why you shouldn't learn Rust
https://www.youtube.com/watch?v=kOFWIvNowXo
https://www.youtube.com/watch?v=kOFWIvNowXo
152デフォルトの名無しさん
2023/07/04(火) 15:58:19.26ID:Ot1h7oR2153デフォルトの名無しさん
2023/07/04(火) 17:54:17.35ID:fS9gKmDv >>147
せやね
かなぁとは思ってたんやけど時間なくて試せなかった
whichFoo()の条件式を時間のsystem時間の下一桁が奇数か偶数かで決めるように変項したら当たり前みたいにRVOが聞かなくなった
https://ideone.com/T6QJKv
まぁそりゃそうかもね、aかbかどっちが返されるか分からないのに両方とも呼び出し側stackに領域確保してまでRVO効かす事はしないみたいやね
もちろん「フラグメンテーション上等、ローカルスタックに穴開いてもその処理終わるまでなんやから無視、無駄コピーしない事最優先」って実装もできたんやろうけどそうはなってないみたいやな
多分この辺は実装依存なんやろ
せやね
かなぁとは思ってたんやけど時間なくて試せなかった
whichFoo()の条件式を時間のsystem時間の下一桁が奇数か偶数かで決めるように変項したら当たり前みたいにRVOが聞かなくなった
https://ideone.com/T6QJKv
まぁそりゃそうかもね、aかbかどっちが返されるか分からないのに両方とも呼び出し側stackに領域確保してまでRVO効かす事はしないみたいやね
もちろん「フラグメンテーション上等、ローカルスタックに穴開いてもその処理終わるまでなんやから無視、無駄コピーしない事最優先」って実装もできたんやろうけどそうはなってないみたいやな
多分この辺は実装依存なんやろ
154デフォルトの名無しさん
2023/07/04(火) 18:53:05.89ID:axzJnblJ Rustはなんでsimd命令を安定版で使えないんだろうか。
155デフォルトの名無しさん
2023/07/04(火) 19:16:47.25ID:Z5BWnaiC A-simdラベルつきのissues一通り読んでくれば
156デフォルトの名無しさん
2023/07/04(火) 21:51:42.30ID:SetT7x0B157デフォルトの名無しさん
2023/07/05(水) 01:56:15.57ID:jiFtnYl0 多次元配列の実装ってブロードキャストのところが結構ムズいな。今かなり苦労してるわ。とりあえずnumpyのメジャーな機能はすべて実装したものをrust純正で作りたいか。
158デフォルトの名無しさん
2023/07/05(水) 05:24:25.09ID:QQHh6K/1 足りない次元を前から詰めていくだけでは?
それでうまく揃えられなかったらエラー
それでうまく揃えられなかったらエラー
159デフォルトの名無しさん
2023/07/05(水) 08:04:26.42ID:y+DtViwf rustってマスコットも可愛いし
全てが完璧だよな
全てが完璧だよな
160デフォルトの名無しさん
2023/07/05(水) 08:08:30.35ID:BYWVWFg9 golang なんてマスコットがきもすぎて皆逃げだしたもんな
161デフォルトの名無しさん
2023/07/05(水) 10:16:26.75ID:zDnJAWSM あれは何周回っても逆に良いとはならないのがすごい
162デフォルトの名無しさん
2023/07/05(水) 15:06:58.72ID:5Lz4OcyC163デフォルトの名無しさん
2023/07/05(水) 19:58:33.55ID:p4qutnW6 ʕ◔ϖ◔ʔ < 呼んだ?
164デフォルトの名無しさん
2023/07/05(水) 20:49:18.89ID:jiFtnYl0 とりあえず、Rustで多次元配列の実装自体は大分進んできたけど、配列の値は構造体の中にVec型で持つべきかそれとも他の配列構造体においても同じデータをコピーせずに使い回せるようにするために&Vec型で持たせるべきか悩んでるんだよね。&Vec型だとライフタイムの指定とか複数の可変参照について考えなくちゃいけないからだるいんだけど、一つのデータから複数の配列構造体がコピーなしで作れるんだよな。どうするべきか。
165デフォルトの名無しさん
2023/07/05(水) 21:19:29.23ID:Svd9YdDH Rustの基礎常識
長さを変えうる場合を除いて&Vecや&mut Vecの受け渡しをしない
長さを変えうる場合を除いて&Vecや&mut Vecの受け渡しをしない
166デフォルトの名無しさん
2023/07/05(水) 21:46:41.90ID:jiFtnYl0 >>165
配列構造体、ここではNdarray構造体と呼ぶことにする。Ndarray構造体に多次元配列のデータを持たせる。ただし、Ndarray構造体は配列の中身の情報をVec型で保持してるとするこれをdata属性と言うことにする。すると、Ndarray構造体の2つインスタンスに共通のdata属性を持たせることがムズいんですよ。キャッシュの効率的に共通したメモリを占有するdataを持たしたいときがかなりあるのでそこで悩んでいるんですね。
配列構造体、ここではNdarray構造体と呼ぶことにする。Ndarray構造体に多次元配列のデータを持たせる。ただし、Ndarray構造体は配列の中身の情報をVec型で保持してるとするこれをdata属性と言うことにする。すると、Ndarray構造体の2つインスタンスに共通のdata属性を持たせることがムズいんですよ。キャッシュの効率的に共通したメモリを占有するdataを持たしたいときがかなりあるのでそこで悩んでいるんですね。
167デフォルトの名無しさん
2023/07/05(水) 21:50:12.76ID:drWGyPEK データ構造体をコードで示すべし
168デフォルトの名無しさん
2023/07/05(水) 21:59:42.44ID:SEWIBrGC なにも考えたくなければRc<[T]>でも使ってれば
169デフォルトの名無しさん
2023/07/05(水) 22:02:51.53ID:ZkaWWEhA 一応pytorchの例だと_で終わるメソッドはin-placeで配列を書き換える
170デフォルトの名無しさん
2023/07/05(水) 22:06:34.58ID:jiFtnYl0 Ndarray構造体は簡単に書くと以下のような感じになる。
struct Ndarray<T> {
pub data: Vec<T>,
pub shape: Vec<usize>,
pub stride Vec<usize>,
}
実際のコードではTに関する制約条件も入ってるけどここでは本質的ではないので書かないことにする。
Ndarray構造体を多次元配列の要素に関する情報をdataに持っている。shapeには多次元配列の形状に関する情報が入ってる。ここで、2つのNdarrayインスタンスに同じdataを共有しているような感じにしたいんですよ。勿論、dataのコピーはキャッシュの効率的になしということで。
struct Ndarray<T> {
pub data: Vec<T>,
pub shape: Vec<usize>,
pub stride Vec<usize>,
}
実際のコードではTに関する制約条件も入ってるけどここでは本質的ではないので書かないことにする。
Ndarray構造体を多次元配列の要素に関する情報をdataに持っている。shapeには多次元配列の形状に関する情報が入ってる。ここで、2つのNdarrayインスタンスに同じdataを共有しているような感じにしたいんですよ。勿論、dataのコピーはキャッシュの効率的になしということで。
171デフォルトの名無しさん
2023/07/05(水) 22:27:08.29ID:Svd9YdDH 途中で伸び縮みするのか否か
途中で値が書き換わるのか否か
途中で値が書き換わるのか否か
172デフォルトの名無しさん
2023/07/05(水) 22:30:04.73ID:QQHh6K/1 いやいや数値計算のライブラリでデフォルト共有とかまずないからコピーで実装してくれ
173デフォルトの名無しさん
2023/07/05(水) 22:39:25.32ID:Svd9YdDH >>164で&Vecを渡そうとしていたから何も書き換わらないと判断すると
コピーするのは無駄
コピーするのは無駄
174デフォルトの名無しさん
2023/07/06(木) 01:08:51.91ID:sds/6LG1 当面コピーでよくね?
numpyの値受け渡しもcall by valueで毎回コピーしてるんじゃないの?
numpyの値受け渡しもcall by valueで毎回コピーしてるんじゃないの?
175デフォルトの名無しさん
2023/07/06(木) 01:17:08.65ID:FeGm4Src コピーするメリットがない
普通に&[T]渡し
普通に&[T]渡し
176デフォルトの名無しさん
2023/07/06(木) 01:38:49.41ID:EXYiMe2p お前らエロ画像ぶっこ抜くときもRust使ってんの?
177デフォルトの名無しさん
2023/07/06(木) 02:02:58.99ID:aaYD2+pH Rustならエロも安全さ
178デフォルトの名無しさん
2023/07/06(木) 03:18:32.83ID:pKHb2iZt179デフォルトの名無しさん
2023/07/06(木) 03:21:51.88ID:pKHb2iZt >>175
Rustは構造体の使用的に属性に参照渡しするのが結構ダルいのではと思っています。正直、自分はライフタイムの`aとかいう感じの修飾子に関してあまり理解できてない
Rustは構造体の使用的に属性に参照渡しするのが結構ダルいのではと思っています。正直、自分はライフタイムの`aとかいう感じの修飾子に関してあまり理解できてない
180デフォルトの名無しさん
2023/07/06(木) 03:30:31.36ID:pKHb2iZt >>174
Numpyはデフォルトでは浅いコピー、要は参照で渡してるっぽいです。自分が調べてみた感じでは。
Numpyはデフォルトでは浅いコピー、要は参照で渡してるっぽいです。自分が調べてみた感じでは。
181デフォルトの名無しさん
2023/07/06(木) 04:40:27.15ID:ZBNoJ3oS スレチですが、
k0 レジスタを、opmask レジスタとして predicate
としては使用できない、ということで正しいのでしょうか?
つまり、
EVEX.512.0F.W0 5E /r
VDIVPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er}
と書いてある場合、{k1} の部分は、{k2}や{k3}
などを指定できて、EVEX.aaa の部分には、2や3など、
1〜7 の数値が指定できますが、0 だけは指定できないのでしょう
か? しかし、それだと、k0 のビットが常に全て 1 である
という便利な性質が利用できない気がします。
もしかして、たとえば、k2 レジスタに k0 レジスタの値を
代入してから、{k1}の部分を{k2}と書け、と言うことなんで
しょうか。
だとすれば、なぜ、そんな回りくどい事を。
k0 レジスタを、opmask レジスタとして predicate
としては使用できない、ということで正しいのでしょうか?
つまり、
EVEX.512.0F.W0 5E /r
VDIVPS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst{er}
と書いてある場合、{k1} の部分は、{k2}や{k3}
などを指定できて、EVEX.aaa の部分には、2や3など、
1〜7 の数値が指定できますが、0 だけは指定できないのでしょう
か? しかし、それだと、k0 のビットが常に全て 1 である
という便利な性質が利用できない気がします。
もしかして、たとえば、k2 レジスタに k0 レジスタの値を
代入してから、{k1}の部分を{k2}と書け、と言うことなんで
しょうか。
だとすれば、なぜ、そんな回りくどい事を。
182デフォルトの名無しさん
2023/07/06(木) 05:15:09.86ID:FeGm4Src >>178
書き換えありの場合
同時共有しないなら単純に&mut [T]渡し
共有するならスレッド内かスレッド間か排他制御の粒度や種類はどうかなどで分かれる
例えばスレッド間で共有しつつ書き込みありで排他制御の粒度はスライス全体で読み込み複数同時可ならばArc<RwLock<&mut [T]>>など
書き換えありの場合
同時共有しないなら単純に&mut [T]渡し
共有するならスレッド内かスレッド間か排他制御の粒度や種類はどうかなどで分かれる
例えばスレッド間で共有しつつ書き込みありで排他制御の粒度はスライス全体で読み込み複数同時可ならばArc<RwLock<&mut [T]>>など
183デフォルトの名無しさん
2023/07/06(木) 06:11:31.90ID:FeGm4Src すまん&mutはもちろん不要
Arc<RwLock<[T]>> ね
配列からでなくVecからなら
Arc<RwLock<Vec<T>>> か
長さ変わらないならBox化して
Arc<RwLock<Box<[T]>>>
Arc<RwLock<[T]>> ね
配列からでなくVecからなら
Arc<RwLock<Vec<T>>> か
長さ変わらないならBox化して
Arc<RwLock<Box<[T]>>>
184デフォルトの名無しさん
2023/07/06(木) 08:06:47.31ID:pjKGVGBZ185デフォルトの名無しさん
2023/07/06(木) 12:21:28.35ID:zocpc7Jo >>164
lifetime 付けたくないなら
struct Ndarray<T> {
pub data: Option<&Vec<T>>,
pub shape: Option<&Vec<usize>>,
pub stride Option<&Vec<usize>>,
}
lifetime 付けたくないなら
struct Ndarray<T> {
pub data: Option<&Vec<T>>,
pub shape: Option<&Vec<usize>>,
pub stride Option<&Vec<usize>>,
}
186デフォルトの名無しさん
2023/07/06(木) 12:24:16.16ID:zocpc7Jo >>176
初めてのRustはエロ収集scrapingツールだった
初めてのRustはエロ収集scrapingツールだった
187デフォルトの名無しさん
2023/07/06(木) 14:30:31.20ID:aQspz1Zu ネタにマジレスですまんが、スクレーピングみたいのってRust得意なんけ
188デフォルトの名無しさん
2023/07/06(木) 14:53:35.46ID:3Kmo4orY 得意かは知らないが非同期io機能が充実しててやりやすい
189デフォルトの名無しさん
2023/07/06(木) 17:09:56.98ID:rXBnP+Dg rustに全てを置いてきた
190デフォルトの名無しさん
2023/07/06(木) 21:21:05.78ID:fNr5Fd/6 >>185
ないわw
ないわw
191デフォルトの名無しさん
2023/07/06(木) 21:34:07.17ID:24F0wnkd シャローコピーってスライス代入と普通の代入の時だけでしょ?
ディープコピーは...演算子を使う
さらにin-place演算子(+=など)は変数を書き換える
それ以外は全てコピーを作って返す
これがnumpy
ディープコピーは...演算子を使う
さらにin-place演算子(+=など)は変数を書き換える
それ以外は全てコピーを作って返す
これがnumpy
192デフォルトの名無しさん
2023/07/06(木) 21:39:43.66ID:24F0wnkd ndarrayはスライスをマクロで定義している
さらにスライスはArrayViewを返す
これは真似た方が良い
あとはslice_mut...assignという書き方を踏襲するかどうか
さらにスライスはArrayViewを返す
これは真似た方が良い
あとはslice_mut...assignという書き方を踏襲するかどうか
193デフォルトの名無しさん
2023/07/07(金) 02:03:56.84ID:dzAVAX7p >>192
自分は初学者でも分かりやすいように気本的に配列に関する全ての操作はNdarray構造体に押し込みたいんだよね。
自分は初学者でも分かりやすいように気本的に配列に関する全ての操作はNdarray構造体に押し込みたいんだよね。
194デフォルトの名無しさん
2023/07/07(金) 03:34:18.30ID:LxI5CxNo ダメそう
195デフォルトの名無しさん
2023/07/07(金) 04:58:02.59ID:puo7kNQ2 オプソのするつもりならRustに反対しないが
オプソにするつもりの無いプロジェクトなら
迷わずC/C++ジャマイカ?
オプソにするつもりの無いプロジェクトなら
迷わずC/C++ジャマイカ?
196デフォルトの名無しさん
2023/07/07(金) 11:05:05.39ID:dzAVAX7p RustでNumpyライクなクレートを制作中だけど、ある程度形になったら公開するつもりだよ。OSSにするつもりだし。
197デフォルトの名無しさん
2023/07/07(金) 12:30:09.61ID:98SFipJR >>193
rust使いに初心者がいるとは思えないのだが
ということはやはりRcで持つということになるんかね
chainerのarrayの実装もshared_ptrで持ってる
https://github.com/chainer/chainer/blob/master/chainerx_cc/chainerx/array_body.h
rust使いに初心者がいるとは思えないのだが
ということはやはりRcで持つということになるんかね
chainerのarrayの実装もshared_ptrで持ってる
https://github.com/chainer/chainer/blob/master/chainerx_cc/chainerx/array_body.h
198デフォルトの名無しさん
2023/07/07(金) 13:01:06.40ID:8V8sPKbL まぁでも実際には難しいやろな
かつてプログラミングの世界を席巻していたPascalを駆逐してCが覇権を握ったのは多分基本的な関数の呼び出し方式をcall by refference からcall by valueね変更したのが大きい
cpuの性能が上がるにつれ整数型とか浮動小数点型の受け渡し時程度なら毎回値をコピーする実装にしてもそれで落ちるパフォーマンスの低下はやはりcall by valueの持つ“読みやすさ、組みやすさ”の優位性が際立ってきた
でもとはいえ毎回呼び出しのたびに値をコピーするcall by valueに全統一するのは無理なので文字列やベクトル処理についてはcall by refferenceをえらべるようなよくいえば柔軟、悪くいえば場当たり的な実装にしたのがCが覇権を握った最大の要因かもしれない
しかし今日さらにプログラミング言語の研究が進んでRVO技術などを利用して"call by valueの文法なのにコピーしない"という事が可能になってきて話が違ってきたのは事実、この先この技術がさらに発展すれば“call by valueを使わないベクトル処理ライブラリ”なんてものが出てきてもおかしくはない
でもこのRVOはまだまだ使いにくい、Rustの資料色々読んでも「関数の戻り値の受け渡しの際必ずしもコピーが発生するわけではない」程度の話しか出てこない、この辺は今現在開発がどんどん進んで行っててまだまだ“企画”としてまとめられる段階にないんやろ
だとすると現状“ベクトル処理ライブラリ”をまとめるならcall by refferenceを使う他ない
問題はその際発生するlife time注釈をどうするかの問題、しかしコレもRustの版が進むにつれ変化している“開発途上”の立ち位置で“注釈の省略”の機能を了して“一才注釈なしで使える”はちょっと難しいかも
かつてプログラミングの世界を席巻していたPascalを駆逐してCが覇権を握ったのは多分基本的な関数の呼び出し方式をcall by refference からcall by valueね変更したのが大きい
cpuの性能が上がるにつれ整数型とか浮動小数点型の受け渡し時程度なら毎回値をコピーする実装にしてもそれで落ちるパフォーマンスの低下はやはりcall by valueの持つ“読みやすさ、組みやすさ”の優位性が際立ってきた
でもとはいえ毎回呼び出しのたびに値をコピーするcall by valueに全統一するのは無理なので文字列やベクトル処理についてはcall by refferenceをえらべるようなよくいえば柔軟、悪くいえば場当たり的な実装にしたのがCが覇権を握った最大の要因かもしれない
しかし今日さらにプログラミング言語の研究が進んでRVO技術などを利用して"call by valueの文法なのにコピーしない"という事が可能になってきて話が違ってきたのは事実、この先この技術がさらに発展すれば“call by valueを使わないベクトル処理ライブラリ”なんてものが出てきてもおかしくはない
でもこのRVOはまだまだ使いにくい、Rustの資料色々読んでも「関数の戻り値の受け渡しの際必ずしもコピーが発生するわけではない」程度の話しか出てこない、この辺は今現在開発がどんどん進んで行っててまだまだ“企画”としてまとめられる段階にないんやろ
だとすると現状“ベクトル処理ライブラリ”をまとめるならcall by refferenceを使う他ない
問題はその際発生するlife time注釈をどうするかの問題、しかしコレもRustの版が進むにつれ変化している“開発途上”の立ち位置で“注釈の省略”の機能を了して“一才注釈なしで使える”はちょっと難しいかも
199デフォルトの名無しさん
2023/07/07(金) 13:05:19.96ID:ESNGSxIs >>197
初心者がRustに参入しやすくなるようなライブラリを作ることが目標だから。私自身も初心者に毛が生えたようなレベルだし。
同じ可変参照を持つ構造体のインスタンスが複数作られることを考慮してるからRxとかArcを使うことになる可能性は高い。
初心者がRustに参入しやすくなるようなライブラリを作ることが目標だから。私自身も初心者に毛が生えたようなレベルだし。
同じ可変参照を持つ構造体のインスタンスが複数作られることを考慮してるからRxとかArcを使うことになる可能性は高い。
200デフォルトの名無しさん
2023/07/07(金) 13:17:59.91ID:98SFipJR いや高いじゃなくてw
201デフォルトの名無しさん
2023/07/07(金) 13:29:06.48ID:UaYcujNV >>198
馬鹿には無理
馬鹿には無理
202デフォルトの名無しさん
2023/07/07(金) 15:12:40.92ID:ex1cRp2w >>198
パフォーマンス?なんか思い込み主導のでたらめな話が書かれてるな
PASCALは教育用の言語でCは高級アセンブラみたいな実用言語
比べるほうがおかしい
pascalはPコードを吐く
Cは実行ファイルを吐く
パフォーマンスを考えるならそこから考えろよ
もともとpascal自体の活躍の場がない
移植性でCがドンドン実用化されてすそ野が広がった
Pascalはほぼ教育分野が主な活動の場であって大学などで2000年代初頭まで主に使われた
1990年中ぐらいから言語自体より何が出来るかの方が重要視されだした
UNIXがらみのCのツール(yacc lex)などを使う実用の方が教育の中心となりPascalが使われなくなった
パフォーマンス?なんか思い込み主導のでたらめな話が書かれてるな
PASCALは教育用の言語でCは高級アセンブラみたいな実用言語
比べるほうがおかしい
pascalはPコードを吐く
Cは実行ファイルを吐く
パフォーマンスを考えるならそこから考えろよ
もともとpascal自体の活躍の場がない
移植性でCがドンドン実用化されてすそ野が広がった
Pascalはほぼ教育分野が主な活動の場であって大学などで2000年代初頭まで主に使われた
1990年中ぐらいから言語自体より何が出来るかの方が重要視されだした
UNIXがらみのCのツール(yacc lex)などを使う実用の方が教育の中心となりPascalが使われなくなった
203デフォルトの名無しさん
2023/07/07(金) 16:10:55.60ID:LxMJB/uy やりたいことが
・変更されない間は同じデータを共有する
・変更が必要になったらそこで自分専用に複製する
であれば一般にcopy-on-writeとかclone-on-write(cow)って呼ばれるパターン
RustにもCowって型があるけどこれは原本がはっきりしてる場合じゃないと使い難くて
全てのデータが対等というか原本が特定できない状況ならRc、Arcのmake_mutで似たようなことができる
ndarray使ったことないけどドキュメント見た感じだとArcArrayが似たようなことしてそう
・変更されない間は同じデータを共有する
・変更が必要になったらそこで自分専用に複製する
であれば一般にcopy-on-writeとかclone-on-write(cow)って呼ばれるパターン
RustにもCowって型があるけどこれは原本がはっきりしてる場合じゃないと使い難くて
全てのデータが対等というか原本が特定できない状況ならRc、Arcのmake_mutで似たようなことができる
ndarray使ったことないけどドキュメント見た感じだとArcArrayが似たようなことしてそう
204デフォルトの名無しさん
2023/07/07(金) 16:21:09.69ID:LxMJB/uy 補足というかドキュメント読めば分かるけど
自分以外が参照してない場合は複製しないでそのまま変更するから余計なコピーは発生しない
自分以外が参照してない場合は複製しないでそのまま変更するから余計なコピーは発生しない
205デフォルトの名無しさん
2023/07/07(金) 16:23:08.62ID:kooiOW/g206デフォルトの名無しさん
2023/07/07(金) 16:24:54.69ID:kooiOW/g RustがC/C++と比べて向いてない分野は沢山指摘されているが、
・ゲーム
・GUI
・大規模プログラム
・IDEが使いたい人
・パソコン用アプリ
Rustが向いているかもしれない分野は
・CUIの小規模プログラム
・サーバーサイドプログラム
・ゲーム
・GUI
・大規模プログラム
・IDEが使いたい人
・パソコン用アプリ
Rustが向いているかもしれない分野は
・CUIの小規模プログラム
・サーバーサイドプログラム
207デフォルトの名無しさん
2023/07/07(金) 16:44:26.36ID:+Wkjm5FQ やべえ全く同意できねえ
パソコン用プログラムってどういうことだよせめてデスクトップアプリとかマシな言い方有るだろ
パソコン用プログラムってどういうことだよせめてデスクトップアプリとかマシな言い方有るだろ
208デフォルトの名無しさん
2023/07/07(金) 16:47:26.05ID:/zlan1BL >>206はいつものデタラメ君
209デフォルトの名無しさん
2023/07/07(金) 16:48:41.65ID:Mh36zzjY Delphiってpascalじゃなかったっけ?
210デフォルトの名無しさん
2023/07/07(金) 16:53:58.33ID:BfxSXh+T >>208
デタラメに感じないんだけど
デタラメに感じないんだけど
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 高市首相の答弁書に「台湾有事答えない」と明記 存立危機発言当時 ★2 [蚤の市★]
- 【ド軍】山本由伸、WBC出場を決断!ドジャースが本人の意向を尊重、佐々木朗希はチームが故障歴を懸念で不参加 [鉄チーズ烏★]
- 米大統領報道官「日本と強固な同盟維持、中国とも協力」 [少考さん★]
- JA全農が「新おこめ券」…来年9月末の有効期限を新設、必要経費のみ上乗せ ★2 [蚤の市★]
- ミス・ユニバース フィンランド代表の「つり目」写真が波紋… 本人釈明も批判やまず 協会謝罪「徹底的に検証」へ [冬月記者★]
- 【芸能】瀧本美織 冬の八重洲に美声響かせた「歌って心がぽかぽか温まりました」 [湛然★]
- キ...キャ...キャ...キャン...
- (´・ω・`)おはよ
- 【悲報】女さん「ハローワークで仕事を探してる3-40代の中年男性いるでしょ。あれ何?」 [483447288]
- ( ・᷄ὢ・᷅ )博士メロつき界隈
- 立憲議員、津波警報発令中にニコニコ写真をアップ [279254606]
- 中国人、ガチ超正論。「日本人がアイヌに対してやったことを『問題ない』とするなら、中国が日本人に同じことをしても文句ないだろう?」 [314039747]
