File: hao-he.cpp

package info (click to toggle)
blitz%2B%2B 1%3A0.9-10
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 12,684 kB
  • ctags: 12,926
  • sloc: cpp: 97,336; sh: 8,422; fortran: 1,208; makefile: 688; f90: 596
file content (150 lines) | stat: -rw-r--r-- 2,917 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * This benchmark times the performance of B += sqr(A), where A and B
 * are complex<double> arrays.
 *
 * Note: need to use -mv8 for SPARC v8.
 */

#include <blitz/array.h>
#include <blitz/timer.h>

BZ_USING_NAMESPACE(blitz)

#include <blitz/vector.h>

typedef Array<complex<double>,1> CArray;

void setup(Array<complex<double>,1>& A, Array<complex<double>,1>& B)
{
    int n = A.extent(firstDim);

    for (int i=0; i < n; ++i)
    {
        double x=-10.+20./(n-1.0)*i;
        A(i)=sin(x);
        B(i)=sin(x);
    }
}

void version1(CArray& A, CArray& B, int nIters)
{
    Timer timer;

    // Array notation
    setup(A, B);
    timer.start();
    for (int i=0; i < nIters; ++i)
    {
        B += A*A;
    }
    timer.stop();
    cout << "Time using array notation b += a*a: " << timer.elapsedSeconds()
         << endl;
}

void version2(CArray& A, CArray& B, int nIters)
{
    // Array notation, using sqr(a)
    Timer timer;

    setup(A,B);
    timer.start();
    for (int i=0; i < nIters; ++i)
    {
        B += sqr(A);
    }
    timer.stop();
    cout << "Time using array notation b += sqr(a): " << timer.elapsedSeconds()
         << endl;
}

void version2c(CArray& A, CArray& B)
{
    B += sqr(A);
}

void version2b(CArray& A, CArray& B, int nIters)
{
    // Array notation, using sqr(a)
    Timer timer;

    setup(A,B);
    timer.start();
    for (int i=0; i < nIters; ++i)
    {
        version2c(A,B);
    }
    timer.stop();
    cout << "Time using array notation b += sqr(a): " << timer.elapsedSeconds()
         << endl;
}

void version3(CArray& A, CArray& B, int nIters)
{
    Timer timer;

    int N = A.extent(firstDim);

    // Low-level implementation
    setup(A,B);
    timer.start();
    for (int i=0; i < nIters; ++i)
    {
        for (int j=0; j < N; ++j)
            B(j) += A(j) * A(j);
    }
    timer.stop();
    cout << "Time using low-level version: " << timer.elapsedSeconds()
         << endl;
}

void version4(CArray& A, CArray& B, int nIters)
{
    Timer timer;

    struct cmplx {
        double re, im;
    };
    cmplx* a = (cmplx*)A.data();
    cmplx* b = (cmplx*)B.data();
    setup(A,B);
    int N = A.extent(firstDim);

    timer.start();
    for (int i=0; i < nIters; ++i)
    {
        for (int j=0; j < N; ++j)
        {
            double ar = a[j].re;
            double ai = a[j].im;
            b[j].re += ar*ar - ai*ai;
            b[j].im += 2 * ar * ai;
        }
    }
    timer.stop();
    cout << "Time using really low-level version: " << timer.elapsedSeconds()
         << endl;
}
           
int run(int N, int nIters)
{
    Array<complex<double>,1> A(N), B(N);

    version1(A,B,nIters);
    version2(A,B,nIters);
    version2b(A,B,nIters);
    version3(A,B,nIters);
    version4(A,B,nIters);

    return 0;
}

int main()
{
    cout << "In-cache:" << endl;
    run(256,39063);

    cout << endl << "Out-of-cache:" << endl;
    run(1000000,10);
}