source: tests/zombies/string-perf/prog-normalize.cfa @ 97453ce

Last change on this file since 97453ce was 08ed947, checked in by Michael Brooks <mlbrooks@…>, 3 years ago

Roll up of string changes for performance testing/improvement, and a couple API features supporting them.

String API changes:
Defining a tuning knob to control the heap growth policy (relapaces former 10% hardcode, downgraded to a default)
Implementing findFrom (allowing find-non-first); leaving find as find-first.

String implementation perf improvements:
Calling C-malloc directly instead of via CFA-alloc.
Replacings loops that copy with memmove calls.
Replacings loops that search for a value with memchr calls.

String perf testing realized:
Makefile supporting several prog-*.cfa, chosen by OPERATION value (implies prog.cfa changes to support the adjusted protocol)
Adjusting the starter/accumulater declarations in PEQ and PTA to behave consistently in cfa v cpp.
Adding tests: allocation, find, normalize, pass-by-val, pass-by-x.
Adding helper shell scripts for: generating flame graphs, collecting/crunching allocation stats using Mubeen's malloc wrappers

  • Property mode set to 100644
File size: 6.9 KB
Line 
1#if defined IMPL_STL_NA_NA
2  #define IMPL_STL
3#endif
4
5#if defined IMPL_BUHR94_NA_NA
6  #define IMPL_BUHR94
7#endif
8
9#if defined IMPL_STL
10  #include <string>
11  #include <iostream>
12  #include <cstdio>
13  using namespace std;
14  #define IMPL_CXX
15
16#elif defined IMPL_CFA_HL_SHARE
17  #define IMPL_CFA_HL
18  #define IMPL_CFA
19
20#elif defined IMPL_CFA_LL_SHARE
21  #define IMPL_CFA_LL
22  #define IMPL_CFA
23
24#elif defined IMPL_CFA_HL_NOSHARE
25  #define IMPL_CFA_HL
26  #define CFA_NOSHARE
27  #define IMPL_CFA
28
29#elif defined IMPL_CFA_LL_NOSHARE
30  #define IMPL_CFA_LL
31  #define CFA_NOSHARE
32  #define IMPL_CFA
33
34#elif defined IMPL_BUHR94
35  #include <iostream>
36  #include <cstdio>
37  #include "/u0/mlbrooks/usys1/sm/string/StringSharing/src/string.h"
38  #define IMPL_CXX
39
40#else
41  #error Bad IMPL_
42#endif
43
44
45#if defined IMPL_CFA_HL
46  #include <string.hfa>
47#elif defined IMPL_CFA_LL
48  #include <string_res.hfa>
49#endif
50
51#if defined CFA_NOSHARE
52  #include <string_sharectx.hfa>
53  #define STRING_SHARING_CONTROL \
54    string_sharectx c = { NO_SHARING };
55#else
56  #define STRING_SHARING_CONTROL
57#endif
58
59#if defined IMPL_CFA
60  #include <math.hfa>
61  extern "C" {
62    void malloc_stats( void );
63  }
64#elif defined IMPL_CXX
65  #include <algorithm>
66  using std::min;
67  #include <malloc.h>
68#endif
69
70#include <time.h>
71#include <stdlib.h> // atoi
72#include <string.h> // strlen, only during setup
73
74#if defined IMPL_STL || defined IMPL_BUHR94
75    #define PRINT(s) std::cout << s << std::endl
76#elif defined IMPL_CFA_HL || defined IMPL_CFA_LL
77    #define PRINT(s) sout | s;
78#else
79    #error Unhandled print case
80#endif
81
82#if defined IMPL_CFA_LL
83    #define STRING_T string_res
84    #define ASSIGN_CHAR(str, idx, val) assignAt(str, idx, val)
85#else
86    #define STRING_T string
87    #define ASSIGN_CHAR(str, idx, val) str[idx] = val
88#endif
89
90#if defined IMPL_CFA
91    #define LEN(str) size(str)
92#elif defined IMPL_STL
93    #define LEN(str) str.length()
94#else
95    #error need LEN definition for this IMPL_
96#endif
97
98double meanLen(int N, char ** strings) {
99    int totalLen = 0;
100    for (int i = 0 ; i < N; i ++) {
101        totalLen += strlen(strings[i]);
102    }
103    return (double)totalLen / (double)N;
104}
105
106volatile int checkthis = 0;
107#define MAYBE( op ) if (checkthis) { op; }
108
109// setup, not being timed, nor judged for aesthetics
110void makeSuperCorpus( STRING_T & target, int corpusLen, char ** corpus, int scSize, char scDelimiter ) {
111    char delimiterStr[2] = { scDelimiter, '\0' };
112    for ( int i = 0;  i < scSize; i++ ) {
113        target += corpus[ i % corpusLen ];
114        target += delimiterStr;
115    }
116}
117
118// the function at issue
119
120#if defined IMPL_CFA_HL
121void processThing( string & thing, char magicChar ) {
122    MAYBE(PRINT(thing));
123    size_t foundPos;
124    for (;;) {
125        size_t size_thing = size(thing);
126        foundPos = find(thing, magicChar);
127        if( foundPos == size_thing ) break;
128        string mcOccur = thing(foundPos, foundPos+1)`shareEdits;
129        mcOccur = "";
130    }
131    return thing;
132}
133
134#elif defined IMPL_CFA_LL
135void processThing( string_res & thing, char magicChar ) {
136    MAYBE(PRINT(thing));
137    size_t foundPos;
138    for (;;) {
139        size_t size_thing = size(thing);
140        foundPos = find(thing, magicChar);
141        if( foundPos == size_thing ) break;
142        string_res mcOccur = { thing, SHARE_EDITS, foundPos, foundPos+1 };
143        mcOccur = "";
144    }
145}
146
147#elif defined IMPL_STL
148void processThing( string & thing, char magicChar ) {
149    MAYBE(PRINT(thing));
150    size_t foundPos;
151    for (;;) {
152        size_t size_thing = thing.length();
153        foundPos = thing.find(magicChar);
154        if (foundPos == string::npos) break;
155        thing.erase(foundPos, 1);
156    }
157}
158
159#endif
160
161/*
162void runCorrectnessDemo(char** corpus, int corpusLen) {
163    STRING_T item = "asdf";    PRINT( processThing( item, '-' ) );
164    item = "as-df";            PRINT( processThing( item, '-' ) );
165    item = "-asdf-";           PRINT( processThing( item, '-' ) );
166    item = "-";                PRINT( processThing( item, '-' ) );
167    for ( int i = 0; i < corpusLen; i ++ ) {
168        item = corpus[i];      PRINT( processThing( item, '-' ) );
169    }
170
171    STRING_T supercorpus;
172    makeSuperCorpus( supercorpus, corpusLen, corpus, 30, ',');
173    PRINT( supercorpus );
174}
175*/
176
177int main( int argc, char ** argv ) {
178
179    STRING_SHARING_CONTROL
180
181    int corpuslen = 0;
182    char ** corpus = (char**) 0;
183
184    clock_t start, endTarget, end_actual;
185
186    const char * usage_args = "SCsize MagicChar ExecTimeSecs Corpus...";
187    const int static_arg_posns = 4;
188
189    int scSize = -1;
190    char magicChar = '\0';
191    int execTimeSecs = -1;
192
193    switch (min(argc, static_arg_posns)) {
194      case 4: execTimeSecs = atoi(argv[3]);
195      case 3: magicChar = argv[2][0];
196      case 2: scSize = atoi(argv[1]);
197    }
198
199    corpuslen = argc - static_arg_posns;
200    corpus = argv + static_arg_posns;
201
202    if (scSize < 1 || magicChar == '\0' || execTimeSecs < 1 || corpuslen < 1) {
203      printf("usage: %s %s\n", argv[0], usage_args);
204      printf("output:\nxxx,corpusItemCount,corpusMeanLenChars,invcationCountActual,execTimeActualSec\n");
205      exit(1);
206    }
207
208    double meanCorpusLen = meanLen(corpuslen, corpus);
209
210//    runCorrectnessDemo(corpus, corpuslen);
211
212
213    STRING_T supercorpus;
214    makeSuperCorpus( supercorpus, corpuslen, corpus, scSize, ',');
215
216    size_t sc_charlen = LEN(supercorpus);
217
218    start = clock();
219    endTarget = start + CLOCKS_PER_SEC * execTimeSecs;
220
221    volatile unsigned int t = 0;
222    size_t lastChunkEnd = -1;
223    for ( ; t % 10000 != 0 || clock() < endTarget ; t += 1 ) {
224            #if defined OP_PNO
225
226                lastChunkEnd++;
227                if ( lastChunkEnd >= sc_charlen ) {
228                    lastChunkEnd = 0;
229                }
230
231#if defined IMPL_CFA_HL
232                size_t thisChunkEnd = findFrom( supercorpus, lastChunkEnd, ',' );
233                //if (thisChunkEnd == string::npos) throw 1;
234                string chunkProcessed = supercorpus(lastChunkEnd, thisChunkEnd);
235                processThing(chunkProcessed, '-');
236#elif defined IMPL_CFA_LL
237                size_t thisChunkEnd = findFrom( supercorpus, lastChunkEnd, ',' );
238                //if (thisChunkEnd == string::npos) throw 1;
239               
240                string_res chunkProcessed = { supercorpus, COPY_VALUE, lastChunkEnd, thisChunkEnd };
241                processThing( chunkProcessed, '-' );
242#elif defined IMPL_STL
243                size_t thisChunkEnd = supercorpus.find( ',', lastChunkEnd );
244                if (thisChunkEnd == string::npos) throw 1;
245                string chunkProcessed = supercorpus.substr(lastChunkEnd, thisChunkEnd-lastChunkEnd);
246                processThing(chunkProcessed, '-');
247#else
248#error Bad IMPL_
249#endif
250                MAYBE( PRINT(chunkProcessed) );
251
252                lastChunkEnd = thisChunkEnd;
253            #else
254                #error Bad OP_
255            #endif
256    }
257    end_actual = clock();
258    double elapsed = ((double) (end_actual - start)) / CLOCKS_PER_SEC;
259    printf("xxx,%d,%f,%d,%f\n", corpuslen, meanCorpusLen, t, elapsed);
260
261    // malloc_stats();
262
263    return 0;
264}
Note: See TracBrowser for help on using the repository browser.