![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright 2005-2010 Intel Corporation. All Rights Reserved. 00003 00004 This file is part of Threading Building Blocks. 00005 00006 Threading Building Blocks is free software; you can redistribute it 00007 and/or modify it under the terms of the GNU General Public License 00008 version 2 as published by the Free Software Foundation. 00009 00010 Threading Building Blocks is distributed in the hope that it will be 00011 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00012 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Threading Building Blocks; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 As a special exception, you may use this file as part of a free software 00020 library without restriction. Specifically, if other files instantiate 00021 templates or use macros or inline functions from this file, or you compile 00022 this file and link it with other files to produce an executable, this 00023 file does not by itself cause the resulting executable to be covered by 00024 the GNU General Public License. This exception does not however 00025 invalidate any other reasons why the executable file might be covered by 00026 the GNU General Public License. 00027 */ 00028 00029 // Workaround for ICC 11.0 not finding __sync_fetch_and_add_4 on some of the Linux platforms. 00030 #if __linux__ && defined(__INTEL_COMPILER) 00031 #define __sync_fetch_and_add(ptr,addend) _InterlockedExchangeAdd(const_cast<void*>(reinterpret_cast<volatile void*>(ptr)), addend) 00032 #endif 00033 #include <string> 00034 #include <cstring> 00035 #include <cctype> 00036 #include <cstdlib> 00037 #include <cstdio> 00038 #include "tbb/concurrent_hash_map.h" 00039 #include "tbb/blocked_range.h" 00040 #include "tbb/parallel_for.h" 00041 #include "tbb/tick_count.h" 00042 #include "tbb/task_scheduler_init.h" 00043 #include "tbb/tbb_allocator.h" 00044 00045 00047 00049 typedef std::basic_string<char,std::char_traits<char>,tbb::tbb_allocator<char> > MyString; 00050 00051 using namespace tbb; 00052 using namespace std; 00053 00055 static bool Verbose = false; 00056 00058 static int NThread = 1; 00059 00061 long N = 1000000; 00062 const int size_factor = 2; 00063 00065 static bool is_number_of_threads_set = false; 00067 typedef concurrent_hash_map<MyString,int> StringTable; 00068 00070 struct Tally { 00071 StringTable& table; 00072 Tally( StringTable& table_ ) : table(table_) {} 00073 void operator()( const blocked_range<MyString*> range ) const { 00074 for( MyString* p=range.begin(); p!=range.end(); ++p ) { 00075 StringTable::accessor a; 00076 table.insert( a, *p ); 00077 a->second += 1; 00078 } 00079 } 00080 }; 00081 00082 static MyString* Data; 00083 00084 static void CountOccurrences(int nthreads) { 00085 StringTable table; 00086 00087 tick_count t0 = tick_count::now(); 00088 parallel_for( blocked_range<MyString*>( Data, Data+N, 1000 ), Tally(table) ); 00089 tick_count t1 = tick_count::now(); 00090 00091 int n = 0; 00092 for( StringTable::iterator i=table.begin(); i!=table.end(); ++i ) { 00093 if( Verbose && nthreads ) 00094 printf("%s %d\n",i->first.c_str(),i->second); 00095 n += i->second; 00096 } 00097 00098 if (is_number_of_threads_set) { 00099 printf("threads = %d total = %d unique = %u time = %g\n", nthreads, n, unsigned(table.size()), (t1-t0).seconds()); 00100 } else { 00101 if ( nthreads == 1 ) { 00102 printf("serial run total = %d unique = %u time = %g\n", n, unsigned(table.size()), (t1-t0).seconds()); 00103 } else { 00104 printf("parallel run total = %d unique = %u time = %g\n", n, unsigned(table.size()), (t1-t0).seconds()); 00105 } 00106 } 00107 } 00108 00110 00111 struct Sound { 00112 const char *chars; 00113 int rates[3];// begining, middle, ending 00114 }; 00115 Sound Vowels[] = { 00116 {"e", {445,6220,1762}}, {"a", {704,5262,514}}, {"i", {402,5224,162}}, {"o", {248,3726,191}}, 00117 {"u", {155,1669,23}}, {"y", {4,400,989}}, {"io", {5,512,18}}, {"ia", {1,329,111}}, 00118 {"ea", {21,370,16}}, {"ou", {32,298,4}}, {"ie", {0,177,140}}, {"ee", {2,183,57}}, 00119 {"ai", {17,206,7}}, {"oo", {1,215,7}}, {"au", {40,111,2}}, {"ua", {0,102,4}}, 00120 {"ui", {0,104,1}}, {"ei", {6,94,3}}, {"ue", {0,67,28}}, {"ay", {1,42,52}}, 00121 {"ey", {1,14,80}}, {"oa", {5,84,3}}, {"oi", {2,81,1}}, {"eo", {1,71,5}}, 00122 {"iou", {0,61,0}}, {"oe", {2,46,9}}, {"eu", {12,43,0}}, {"iu", {0,45,0}}, 00123 {"ya", {12,19,5}}, {"ae", {7,18,10}}, {"oy", {0,10,13}}, {"ye", {8,7,7}}, 00124 {"ion", {0,0,20}}, {"ing", {0,0,20}}, {"ium", {0,0,10}}, {"er", {0,0,20}} 00125 }; 00126 Sound Consonants[] = { 00127 {"r", {483,1414,1110}}, {"n", {312,1548,1114}}, {"t", {363,1653,251}}, {"l", {424,1341,489}}, 00128 {"c", {734,735,260}}, {"m", {732,785,161}}, {"d", {558,612,389}}, {"s", {574,570,405}}, 00129 {"p", {519,361,98}}, {"b", {528,356,30}}, {"v", {197,598,16}}, {"ss", {3,191,567}}, 00130 {"g", {285,430,42}}, {"st", {142,323,180}}, {"h", {470,89,30}}, {"nt", {0,350,231}}, 00131 {"ng", {0,117,442}}, {"f", {319,194,19}}, {"ll", {1,414,83}}, {"w", {249,131,64}}, 00132 {"k", {154,179,47}}, {"nd", {0,279,92}}, {"bl", {62,235,0}}, {"z", {35,223,16}}, 00133 {"sh", {112,69,79}}, {"ch", {139,95,25}}, {"th", {70,143,39}}, {"tt", {0,219,19}}, 00134 {"tr", {131,104,0}}, {"pr", {186,41,0}}, {"nc", {0,223,2}}, {"j", {184,32,1}}, 00135 {"nn", {0,188,20}}, {"rt", {0,148,51}}, {"ct", {0,160,29}}, {"rr", {0,182,3}}, 00136 {"gr", {98,87,0}}, {"ck", {0,92,86}}, {"rd", {0,81,88}}, {"x", {8,102,48}}, 00137 {"ph", {47,101,10}}, {"br", {115,43,0}}, {"cr", {92,60,0}}, {"rm", {0,131,18}}, 00138 {"ns", {0,124,18}}, {"sp", {81,55,4}}, {"sm", {25,29,85}}, {"sc", {53,83,1}}, 00139 {"rn", {0,100,30}}, {"cl", {78,42,0}}, {"mm", {0,116,0}}, {"pp", {0,114,2}}, 00140 {"mp", {0,99,14}}, {"rs", {0,96,16}}, /*{"q", {52,57,1}},*/ {"rl", {0,97,7}}, 00141 {"rg", {0,81,15}}, {"pl", {56,39,0}}, {"sn", {32,62,1}}, {"str", {38,56,0}}, 00142 {"dr", {47,44,0}}, {"fl", {77,13,1}}, {"fr", {77,11,0}}, {"ld", {0,47,38}}, 00143 {"ff", {0,62,20}}, {"lt", {0,61,19}}, {"rb", {0,75,4}}, {"mb", {0,72,7}}, 00144 {"rc", {0,76,1}}, {"gg", {0,74,1}}, {"pt", {1,56,10}}, {"bb", {0,64,1}}, 00145 {"sl", {48,17,0}}, {"dd", {0,59,2}}, {"gn", {3,50,4}}, {"rk", {0,30,28}}, 00146 {"nk", {0,35,20}}, {"gl", {40,14,0}}, {"wh", {45,6,0}}, {"ntr", {0,50,0}}, 00147 {"rv", {0,47,1}}, {"ght", {0,19,29}}, {"sk", {23,17,5}}, {"nf", {0,46,0}}, 00148 {"cc", {0,45,0}}, {"ln", {0,41,0}}, {"sw", {36,4,0}}, {"rp", {0,36,4}}, 00149 {"dn", {0,38,0}}, {"ps", {14,19,5}}, {"nv", {0,38,0}}, {"tch", {0,21,16}}, 00150 {"nch", {0,26,11}}, {"lv", {0,35,0}}, {"wn", {0,14,21}}, {"rf", {0,32,3}}, 00151 {"lm", {0,30,5}}, {"dg", {0,34,0}}, {"ft", {0,18,15}}, {"scr", {23,10,0}}, 00152 {"rch", {0,24,6}}, {"rth", {0,23,7}}, {"rh", {13,15,0}}, {"mpl", {0,29,0}}, 00153 {"cs", {0,1,27}}, {"gh", {4,10,13}}, {"ls", {0,23,3}}, {"ndr", {0,25,0}}, 00154 {"tl", {0,23,1}}, {"ngl", {0,25,0}}, {"lk", {0,15,9}}, {"rw", {0,23,0}}, 00155 {"lb", {0,23,1}}, {"tw", {15,8,0}}, /*{"sq", {15,8,0}},*/ {"chr", {18,4,0}}, 00156 {"dl", {0,23,0}}, {"ctr", {0,22,0}}, {"nst", {0,21,0}}, {"lc", {0,22,0}}, 00157 {"sch", {16,4,0}}, {"ths", {0,1,20}}, {"nl", {0,21,0}}, {"lf", {0,15,6}}, 00158 {"ssn", {0,20,0}}, {"xt", {0,18,1}}, {"xp", {0,20,0}}, {"rst", {0,15,5}}, 00159 {"nh", {0,19,0}}, {"wr", {14,5,0}} 00160 }; 00161 const int VowelsNumber = sizeof(Vowels)/sizeof(Sound); 00162 const int ConsonantsNumber = sizeof(Consonants)/sizeof(Sound); 00163 int VowelsRatesSum[3] = {0,0,0}, ConsonantsRatesSum[3] = {0,0,0}; 00164 00165 int CountRateSum(Sound sounds[], const int num, const int part) 00166 { 00167 int sum = 0; 00168 for(int i = 0; i < num; i++) 00169 sum += sounds[i].rates[part]; 00170 return sum; 00171 } 00172 00173 const char *GetLetters(int type, const int part) 00174 { 00175 Sound *sounds; int rate, i = 0; 00176 if(type & 1) 00177 sounds = Vowels, rate = rand() % VowelsRatesSum[part]; 00178 else 00179 sounds = Consonants, rate = rand() % ConsonantsRatesSum[part]; 00180 do { 00181 rate -= sounds[i++].rates[part]; 00182 } while(rate > 0); 00183 return sounds[--i].chars; 00184 } 00185 00186 static void CreateData() { 00187 for(int i = 0; i < 3; i++) { 00188 ConsonantsRatesSum[i] = CountRateSum(Consonants, ConsonantsNumber, i); 00189 VowelsRatesSum[i] = CountRateSum(Vowels, VowelsNumber, i); 00190 } 00191 for( int i=0; i<N; ++i ) { 00192 int type = rand(); 00193 Data[i] = GetLetters(type++, 0); 00194 for( int j = 0; j < type%size_factor; ++j ) 00195 Data[i] += GetLetters(type++, 1); 00196 Data[i] += GetLetters(type, 2); 00197 } 00198 MyString planet = Data[12]; planet[0] = toupper(planet[0]); 00199 MyString helloworld = Data[0]; helloworld[0] = toupper(helloworld[0]); 00200 helloworld += ", "+Data[1]+" "+Data[2]+" "+Data[3]+" "+Data[4]+" "+Data[5]; 00201 printf("Message from planet '%s': %s!\nAnalyzing whole text...\n", planet.c_str(), helloworld.c_str()); 00202 } 00203 00205 00206 static void ParseCommandLine( int argc, char* argv[] ) { 00207 int i = 1; 00208 if( i<argc && strcmp( argv[i], "verbose" )==0 ) { 00209 Verbose = true; 00210 ++i; 00211 } 00212 if( i<argc ) 00213 if( !isdigit(argv[i][0]) ) { 00214 fprintf(stderr,"Usage: %s [verbose] [number-of-strings] [number-of-threads]\n",argv[0]); 00215 exit(1); 00216 } else { 00217 N = strtol(argv[i++],0,0); 00218 } 00219 if( i<argc ) 00220 if( !isdigit(argv[i][0]) ) { 00221 fprintf(stderr,"Usage: %s [verbose] [number-of-strings] [number-of-threads]\n",argv[0]); 00222 exit(1); 00223 } else { 00224 NThread = strtol(argv[i++],0,0); 00225 is_number_of_threads_set = true; 00226 } 00227 } 00228 00229 int main( int argc, char* argv[] ) { 00230 srand(2); 00231 ParseCommandLine( argc, argv ); 00232 Data = new MyString[N]; 00233 CreateData(); 00234 if (is_number_of_threads_set) { 00235 task_scheduler_init init(NThread); 00236 CountOccurrences(NThread); 00237 } else { // Number of threads wasn't set explicitly. Run serial and parallel version 00238 { // serial run 00239 task_scheduler_init init_serial(1); 00240 CountOccurrences(1); 00241 } 00242 { // parallel run (number of threads is selected automatically) 00243 task_scheduler_init init_parallel; 00244 CountOccurrences(0); 00245 } 00246 } 00247 delete[] Data; 00248 }
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.