質問するログイン新規登録

回答編集履歴

3

可変長配列を使わないコード

2021/07/25 13:48

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -39,4 +39,21 @@
39
39
  }
40
40
  }
41
41
  ```
42
- もちろん、コンパイル時には最適化オプションを指定してください。
42
+ もちろん、コンパイル時には最適化オプションを指定してください。
43
+
44
+ **追記3**
45
+ > 今回はN=64~2048の2の冪乗の数で計測しようとしています.
46
+
47
+ それなら、可変長配列なんか使わず、次のようにすれば速くなるのではありませんか?
48
+ ```
49
+ #define N 64
50
+
51
+ void naive_rotate(int n, int src[N][N], dst[N][N])
52
+ {
53
+ for (int i = 0; i < N; i++)
54
+ for (int j = 0; j < N; j++)
55
+ dst[i][j] = src[j][N-1-i];
56
+ }
57
+ ```
58
+ 引数の int n は使っていないので不要ですが、呼び出し元を変更しないで済む
59
+ ように残しています。

2

ポインタを使うコードを追加

2021/07/25 13:48

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -23,4 +23,20 @@
23
23
  ただ、`dst[n-1-j][i] = src[i][j];` のように
24
24
  dst を飛び飛びにして、src を連続にするよりも、
25
25
  `dst[i][j] = src[j][n-1-i];` のように
26
- dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
26
+ dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
27
+
28
+ **追記2**
29
+ ポインタにしてみました。添字の計算で掛け算がなくなり速くなるかもしれません。
30
+ 配列のアドレスより前を指すので規格違反ですが、そこはアクセスしません。
31
+ ```C
32
+ void naive_rotate(int n, int src[n][n], int dst[n][n])
33
+ {
34
+ int *dp = dst[0], *sp = src[0] - 1, m = n*n + 1;
35
+ for (int i = 0; i < n; i++) {
36
+ for (int j = 0; j < n; j++)
37
+ *dp++ = *(sp += n);
38
+ sp -= m;
39
+ }
40
+ }
41
+ ```
42
+ もちろん、コンパイル時には最適化オプションを指定してください。

1

転置ではなく回転についての説明

2021/07/24 15:33

投稿

kazuma-s
kazuma-s

スコア8222

answer CHANGED
@@ -15,4 +15,12 @@
15
15
  ループ回数の減少のほうが大きく効いてくるでしょう。
16
16
 
17
17
  配列をポインタに置き換えると高速になることがありますが、
18
- 最近のコンパイラは最適化でこれを勝手にやってくれたりします。
18
+ 最近のコンパイラは最適化でこれを勝手にやってくれたりします。
19
+
20
+ **追記**
21
+ 回転なら愚直に (n*n)回ループするしかないでしょう。
22
+
23
+ ただ、`dst[n-1-j][i] = src[i][j];` のように
24
+ dst を飛び飛びにして、src を連続にするよりも、
25
+ `dst[i][j] = src[j][n-1-i];` のように
26
+ dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。