テーマ「最適化」

1,580 views

Published on

2010/08/07 @hokkaido.pm #1

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,580
On SlideShare
0
From Embeds
0
Number of Embeds
45
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

テーマ「最適化」

  1. 1. テーマ「最適化」
  2. 2. perl スクリプトの最適化を やってみました。
  3. 3. 今回のお題 「カラー画像をモノクロに変換」 変換!
  4. 4. スクリプトの概要 1. ヘッダーを読み込む 2. 画像データを読み込む 3. 画像データを改変 4. ファイルに保存
  5. 5. 実行環境 Mac OS X 10.5.8 CPU Intel Core 2 Duo 2.4 GHz メモリ 4GB 800MHz DDR2 SDRAM perl 5.8.9 テストデータ 6M pixel ( 3008 x 2000 ) 32bit format
  6. 6. 単純なコピー sub test0 { my @argb_test = @argb_src; push @argb_dst, @argb_test; } @argb_src @argb_test 0x12345678 0x12345678 0x12345678 0x12345678 0x12345678 0x12345678 ・ ・ ・ ・ ・ ・
  7. 7. 単純なコピー TEST0: 1 wallclock secs ( 0.38 usr + 0.02 sys = 0.40 CPU) @ 2.50/s (n=1)
  8. 8. モノクロに変換 @argb_src @argb_test 0x12345678 0x004E4E4E 0x12345678 0x004E4E4E 0x12345678 0x004E4E4E ・ ・ ・ ・ ・ ・ Y = 0.29*R + 0.59*G + 0.11*B (※係数は、輝度を求める一般的な値)
  9. 9. モノクロに変換 sub test1 { # Y = 0.29*R + 0.59*G + 0.11*B my @factor = ( 0.30, 0.59, 0.11 ); my @argb_test = @argb_src; for (my $i=0; $i<scalar(@argb_test); $i++) { my $argb = $argb_test[$i]; # ARGB my $r = ( ($argb >> 16) & 0xFF ); my $g = ( ($argb >> 8) & 0xFF ); my $b = ( ($argb >> 0) & 0xFF ); my $y = int( ($r * $factor[0]) + ($g * $factor[1]) + ($b * $factor[2]) ); $argb_test[$i] = ( ($y << 16) + ($y << 8) + $y ); } push @argb_dst, @argb_test; }
  10. 10. モノクロに変換 TEST0: 0 wallclock secs ( 0.38 usr + 0.02 sys = 0.40 CPU) @ 2.50/s (n=1) TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1)
  11. 11. モノクロに変換 〜 その2 実数を排して、固定小数点演算(小数部 8 ビット)で、 モノクロ変換を行う # my @factor = ( 0.30, 0.59, 0.11 ); my @factor = ( int(0.30*256), int(0.59*256), int(0.11*256) ); # my $y = int( ($r*$factor[0]) + ($g*$factor[1]) + ($b*$factor[2]) ); my $y = ( ($r * $factor[0]) + ($g * $factor[1]) + ($b * $factor[2]) ) >> 8; 256 で割る処理を、 8 ビット右シフトに置き換える
  12. 12. モノクロに変換 〜 その2 TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1) TEST2: 14 wallclock secs (13.78 usr + 0.15 sys = 13.93 CPU) @ 0.07/s (n=1) まったく効果なし!
  13. 13. おお ゆうしゃよ こころが おれるとは なさけない
  14. 14. モノクロに変換 〜 その3 ダメもとで、手数を減らしてみた # 最初の実数案にもどす my @factor = ( 0.30, 0.59, 0.11 ); # パースと乗算を一緒に行って、格納処理も最適化! my $y = ($argb & 0xFF) * $factor[2]; $argb >>= 8; $y += ($argb & 0xFF) * $factor[1]; $argb >>= 8; $y += ($argb & 0xFF) * $factor[0]; $argb_test[$i] = 0x010101 * int($y);
  15. 15. モノクロに変換 〜 その3 TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1) TEST3: 11 wallclock secs (10.22 usr + 0.12 sys = 10.34 CPU) @ 0.10/s (n=1) 約 25% 高速化!
  16. 16. モノクロに変換 〜 その4 for 文を map に置き換えてみた my @argb_test = map { my $argb = $_; # ARGB my $y = ($argb & 0xFF) * $factor[2]; $argb >>= 8; $y += ($argb & 0xFF) * $factor[1]; $argb >>= 8; $y += ($argb & 0xFF) * $factor[0]; 0x010101 * int($y); } @argb_src;
  17. 17. モノクロに変換 〜 その4 TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1) TEST4: 9 wallclock secs ( 9.00 usr + 0.20 sys = 9.20 CPU) @ 0.11/s (n=1) 約 33% 高速化!
  18. 18. モノクロに変換 〜 その5 配列を変数に展開してみた # my @factor = ( 0.30, 0.59, 0.11 ); my $fr = 0.30; my $fg = 0.59; my $fb = 0.11;
  19. 19. モノクロに変換 〜 その5 TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1) TEST5: 9 wallclock secs ( 8.68 usr + 0.11 sys = 8.79 CPU) @ 0.11/s (n=1) 約 36% 高速化!
  20. 20. モノクロに変換 〜 その6 ビットシフトの処理をあらかじめ行ってみた my $fr = 0.30 / (1 << 16); my $fg = 0.59 / (1 << 8); my $fb = 0.11 / (1 << 0); # シフトビットが省略できる my @argb_test = map { my $y = ($_ & 0xFF0000) * $fr; $y += ($_ & 0x00FF00) * $fg; $y += ($_ & 0x0000FF) * $fb; 0x010101 * int($y); } @argb_src;
  21. 21. モノクロに変換 〜 その6 TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1) TEST6: 7 wallclock secs ( 7.04 usr + 0.10 sys = 7.14 CPU) @ 0.14/s (n=1) 約 48% 高速化!
  22. 22. モノクロに変換 〜 その7 map の中を 1 行にまとめてみた my @argb_test = map { 0x010101 * int( (($_ & 0xFF0000) * $fr) + (($_ & 0x00FF00) * $fg) + (($_ & 0x0000FF) * $fb) ); } @argb_src;
  23. 23. モノクロに変換 〜 その7 TEST1: 14 wallclock secs (13.71 usr + 0.12 sys = 13.83 CPU) @ 0.07/s (n=1) TEST7: 6 wallclock secs ( 5.44 usr + 0.12 sys = 5.56 CPU) @ 0.18/s (n=1) 約 60% 高速化!
  24. 24. まとめ

×