SlideShare une entreprise Scribd logo
1  sur  36
Télécharger pour lire hors ligne
不遇の標準ライブラリ
歌舞伎座.tech#8「C++初心者会」
@Ryosuke839
自己紹介
• @Ryosuke839
• 某工大情報工学科4年生です
• 画像認識の研究始めました
• C++初心者です
– 規格書暗記してません
– コンパイラのバグ踏んだことありません
• (‘ω’)
今回のテーマ
今回のテーマ
標準ライブラリ
今回のテーマ
標準ライブラリ
今回のテーマ
• 不遇の標準ライブラリ
今回のテーマ
• 不遇の標準ライブラリ
• 次期規格で追加されるライブラリなどのstate
of the artな話題ではありません
• C++98(C++の初期規格)から存在するライブラ
リの話です
– C++に詳しい諸兄はタイトルでピンときているはず
今回のテーマ
• valarray
• C++98から存在します
• 単独でヘッダファイルも持っています
– #include <valarray>
• でも使われてません
今回のテーマ
• valarray
• 数値計算に特化した可変長配列を実現する
テンプレートクラスvalarrayを含んでいます
– vectorと被るような…
• ベクトル演算を簡単に記述できます
• でも使われてません
今回のテーマ
• valarray
• どれだけ使われていないか
• 論文の世界では被引用数が論文の価値の目
安になるらしいので、被include数を示します
被include数@GitHub
100K
1M
10M
100M
被include数@GitHub
100K
1M
10M
100M
これ
被include数@GitHub
0
5M
10M
15M
20M
25M
これ
今回のテーマ
• valarray
• これだけ使われていないのはかわいそう
• 今回は(無理して)使ってみます
– 見た目でわかりやすい画像処理をします
使ってみる
• とりあえずIOを書きます
std::ifstream ifs(name, std::ios::binary);
std::valarray<unsigned char> res;
res.resize(256 * 256);
for (auto& c : res)
ifs.read(reinterpret_cast<char*>(&c), 1);
std::ofstream ofs(name, std::ios::binary);
for (auto& c : data)
ofs.write(reinterpret_cast<const char*>(&c), 1);
使ってみる
• とりあえずIOを書きます
std::ifstream ifs(name, std::ios::binary);
std::valarray<unsigned char> res;
res.resize(256 * 256);
for (auto& c : res)
ifs.read(reinterpret_cast<char*>(&c), 1);
std::ofstream ofs(name, std::ios::binary);
for (auto& c : data)
ofs.write(reinterpret_cast<const char*>(&c), 1);
可変長だけど可変長じゃない!
使ってみる
• あとは処理を書くだけ
auto data = readimg("nico.bmp");
data = (unsigned char)(192) - data / (unsigned char)(2);
writeimg("result.bmp", data);
使ってみる
• あとは処理を書くだけ
auto data = readimg("nico.bmp");
data = (unsigned char)(192) - data / (unsigned char)(2);
writeimg("result.bmp", data);
暗黙の変換はしてくれません
使ってみる
• あとは処理を書くだけ
auto data = readimg("nico.bmp");
data = (unsigned char)(192) - data / (unsigned char)(2);
writeimg("result.bmp", data);
使ってみる
• あとは処理を書くだけ
auto data = readimg("nico.bmp");
data = (unsigned char)(192) - data / (unsigned char)(2);
writeimg("result.bmp", data);
使ってみる
• Sliceも取れます
auto data = readimg("nico.bmp");
data[std::gslice(112 * 256 + 24,
std::valarray<size_t>{32, 160},
std::valarray<size_t>{256, 1})] = (unsigned char)(0);
writeimg("result.bmp", data);
使ってみる
• Sliceも取れます
auto data = readimg("nico.bmp");
data[std::gslice(112 * 256 + 24,
std::valarray<size_t>{32, 160},
std::valarray<size_t>{256, 1})] = (unsigned char)(0);
writeimg("result.bmp", data);
使ってみる
• 比較結果でsliceを作ることもできます
auto data = readimg("nico.bmp");
data[std::gslice(...)] = (unsigned char)(0);
auto text = readimg("text.bmp");
data[text != byte(127)] =
std::valarray<byte>(text[text != byte(127)]);
writeimg("result.bmp", data);
使ってみる
• 比較結果でsliceを作ることもできます
auto data = readimg("nico.bmp");
data[std::gslice(...)] = (unsigned char)(0);
auto text = readimg("text.bmp");
data[text != byte(127)] =
std::valarray<byte>(text[text != byte(127)]);
writeimg("result.bmp", data);
その他の用法
• 内積
• 外積
• ノルム
– L1
– L2
– L∞
(a * b).sum()
a.cshift(1) * b.cshift(-1) - a.cshift(-1) * b.cshift(1)
std::sqrt((a * a).sum())
std::abs(a).sum()
std::abs(a).max()
残念な仕様
• 他にもsin, cos, exp, log等の関数を使えます
– この場合でも引数と戻り値の型は同じです
– 他の型のvalarrayにキャストもできません
• Sliceで元のvalarrayへの参照を取れますが、
sliceのsliceを取ることはできません
– 一旦sliceから新しいvalarrayを生成する必要あり
template<class T> valarray<T> valarray<T>::apply(T func(const T&)) const;
template<class T> valarray<T> operator* (const valarray<T>&, const T&);
template<class T> valarray<T> pow(const valarray<T>&, const valarray<T>&);
残念な仕様
• valarrayがC++に導入されたそもそもの経緯
– C++が開発された80年代はベクトル型計算機の
華の時代
– Fortranではベクトル化最適化が実装されていた
残念な仕様
• valarrayがC++に導入されたそもそもの経緯
– C++が開発された80年代はベクトル型計算機の
華の時代
– Fortranではベクトル化最適化が実装されていた
– C++でもFortran並みの最適化を簡単に実現でき
るよう狙った?[要出典]
– 型の制約がきついのも最適化のため?[要出典]
残念な仕様
• 現在はPC向けCPUでもSSEなどのベクトル命
令が実装されている
– では、valarrayもそれらに最適化されるのでは…?
残念な仕様
• 現在はPC向けCPUでもSSEなどのベクトル命
令が実装されている
– では、valarrayもそれらに最適化されるのでは…?
• ベンチマークしてみます
– Cスタイルの配列とforループ
– std::vectorとstd::transform
– std::valarray
ベンチマーク
gcc clang
array +
for loop
606ms
FPU
660ms
SSE2
vector +
algorithm
603ms
FPU
641ms
SSE2
valarray 603ms
FPU
648ms
SSE2
Add, mul, sum, sqrt, sin, maxを求めるコード
いずれのコンパイラにも高速演算オプション適用
ベンチマーク
gcc clang msvc
array +
for loop
606ms
FPU
660ms
SSE2
vector +
algorithm
603ms
FPU
641ms
SSE2
281ms
SSE2
valarray 603ms
FPU
648ms
SSE2
256ms
SSE2
Add, mul, sum, sqrt, sin, maxを求めるコード
いずれのコンパイラにも高速演算オプション適用
ベンチマーク
gcc clang msvc icc icc+ipp
array +
for loop
606ms
FPU
660ms
SSE2
vector +
algorithm
603ms
FPU
641ms
SSE2
281ms
SSE2
184ms
AVX
valarray 603ms
FPU
648ms
SSE2
256ms
SSE2
45ms
AVX
41ms
AVX(ipp)
Add, mul, sum, sqrt, sin, maxを求めるコード
いずれのコンパイラにも高速演算オプション適用
ベンチマーク
gcc clang msvc icc icc+ipp
array +
for loop
606ms
FPU
660ms
SSE2
47ms
SSE4
27ms
AVX
vector +
algorithm
603ms
FPU
641ms
SSE2
281ms
SSE2
184ms
AVX
valarray 603ms
FPU
648ms
SSE2
256ms
SSE2
45ms
AVX
41ms
AVX(ipp)
Add, mul, sum, sqrt, sin, maxを求めるコード
いずれのコンパイラにも高速演算オプション適用
まとめ
• valarrayは使われてない割には便利です!
– 簡単なベクトル演算をしたい時に俺々ライブラリ
を書くよりはずっと便利 ただし謎の制約多数
– 仕様が独特なので、本格的な演算をしたい場合
は本格的なライブラリを使いましょう
• vector以上に最適化が効きます
• iccでコンパイルするとvectorの数倍速いです
まとめ
• valarrayは使われてない割には便利です!
– 簡単なベクトル演算をしたい時に俺々ライブラリ
を書くよりはずっと便利 ただし謎の制約多数
– 仕様が独特なので、本格的な演算をしたい場合
は本格的なライブラリを使いましょう
• vector以上に最適化が効きます
• iccでコンパイルするとvectorの数倍速いです
– インテルのコンパイラ今日限り特価140,000円!

Contenu connexe

Tendances

constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだGenya Murakami
 
並列化による高速化
並列化による高速化 並列化による高速化
並列化による高速化 sakura-mike
 
brainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusablebrainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusableroodni
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~Takuya Akiba
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜京大 マイコンクラブ
 
x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTtakesako
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解くshindannin
 
SIMDで整数除算
SIMDで整数除算SIMDで整数除算
SIMDで整数除算shobomaru
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装MITSUNARI Shigeo
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxpsMITSUNARI Shigeo
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門Eita Sugimoto
 
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムTakuya Akiba
 

Tendances (20)

constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
並列化による高速化
並列化による高速化 並列化による高速化
並列化による高速化
 
brainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusablebrainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusable
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
 
x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
 
SIMDで整数除算
SIMDで整数除算SIMDで整数除算
SIMDで整数除算
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門
 
プログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズム
 

Similaire à 不遇の標準ライブラリ - valarray

リテラル文字列型までの道
リテラル文字列型までの道リテラル文字列型までの道
リテラル文字列型までの道Satoshi Sato
 
Stan勉強会資料(前編)
Stan勉強会資料(前編) Stan勉強会資料(前編)
Stan勉強会資料(前編) daiki hojo
 
HTMLからの本文抽出
HTMLからの本文抽出HTMLからの本文抽出
HTMLからの本文抽出Lintaro Ina
 
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」Shin Ise
 
AtCoder Beginner Contest 007 解説
AtCoder Beginner Contest 007 解説AtCoder Beginner Contest 007 解説
AtCoder Beginner Contest 007 解説AtCoder Inc.
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺MITSUNARI Shigeo
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テストKen Morishita
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜Hiromi Ishii
 
Web本文抽出 using crf
Web本文抽出 using crfWeb本文抽出 using crf
Web本文抽出 using crfShuyo Nakatani
 
CRF を使った Web 本文抽出
CRF を使った Web 本文抽出CRF を使った Web 本文抽出
CRF を使った Web 本文抽出Shuyo Nakatani
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックスTomoharu ASAMI
 
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと 12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと Haruka Ozaki
 
AtCoder Beginner Contest 012 解説
AtCoder Beginner Contest 012 解説AtCoder Beginner Contest 012 解説
AtCoder Beginner Contest 012 解説AtCoder Inc.
 
Sphinx HTML Theme Hacks
Sphinx HTML Theme HacksSphinx HTML Theme Hacks
Sphinx HTML Theme HacksShoji KUMAGAI
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2Nishida Kansuke
 

Similaire à 不遇の標準ライブラリ - valarray (20)

リテラル文字列型までの道
リテラル文字列型までの道リテラル文字列型までの道
リテラル文字列型までの道
 
Stan勉強会資料(前編)
Stan勉強会資料(前編) Stan勉強会資料(前編)
Stan勉強会資料(前編)
 
HTMLからの本文抽出
HTMLからの本文抽出HTMLからの本文抽出
HTMLからの本文抽出
 
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」
すごいHaskell読書会 in 大阪 #4 「第6章 モジュール」
 
AtCoder Beginner Contest 007 解説
AtCoder Beginner Contest 007 解説AtCoder Beginner Contest 007 解説
AtCoder Beginner Contest 007 解説
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
Tokyo r38
Tokyo r38Tokyo r38
Tokyo r38
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テスト
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
Web本文抽出 using crf
Web本文抽出 using crfWeb本文抽出 using crf
Web本文抽出 using crf
 
CRF を使った Web 本文抽出
CRF を使った Web 本文抽出CRF を使った Web 本文抽出
CRF を使った Web 本文抽出
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
 
C++11のつかいかた
C++11のつかいかたC++11のつかいかた
C++11のつかいかた
 
Haikara
HaikaraHaikara
Haikara
 
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと 12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
 
AtCoder Beginner Contest 012 解説
AtCoder Beginner Contest 012 解説AtCoder Beginner Contest 012 解説
AtCoder Beginner Contest 012 解説
 
Sphinx HTML Theme Hacks
Sphinx HTML Theme HacksSphinx HTML Theme Hacks
Sphinx HTML Theme Hacks
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 

不遇の標準ライブラリ - valarray