Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4UniformRandPool.cc
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id:$
28 //
29 // G4UniformRandPool implementation
30 //
31 // Author: A.Dotti (SLAC)
32 // ------------------------------------------------------------
33 
34 #include "G4UniformRandPool.hh"
35 #include "globals.hh"
36 #include "G4Threading.hh"
37 #include "G4AutoDelete.hh"
38 
39 #include <climits>
40 #include <stdlib.h>
41 #include <algorithm>
42 #include <cstring>
43 
44 // Not aligned memory
45 //
47 {
48  buffer = new G4double[ps];
49 }
50 
52 {
53  delete[] buffer;
54 }
55 
56 #if defined(WIN32)
57 // No bother with WIN
59 {
60  create_pool(buffer,ps);
61 }
63 {
64  destroy_pool(buffer);
65 }
66 
67 #else
68 
69 // Align memory pools
70 // Assumption is: static_assert(sizeof(G4double)*CHAR_BIT==64)
71 //
73 {
74  // POSIX standard way
75  G4int errcode = posix_memalign( (void**) &buffer ,
76  sizeof(G4double)*CHAR_BIT,
77  ps*sizeof(G4double));
78  if ( errcode != 0 )
79  {
80  G4Exception("G4UniformRandPool::create_pool_align()",
81  "InvalidCondition", FatalException,
82  "Cannot allocate aligned buffer");
83  return;
84  }
85  return;
86 }
87 
89 {
90  free(buffer);
91 }
92 #endif
93 
95  : size(G4UNIFORMRANDPOOL_DEFAULT_POOLSIZE), buffer(0), currentIdx(0)
96 {
97  if ( sizeof(G4double)*CHAR_BIT==64 )
98  {
100  }
101  else
102  {
104  }
105  Fill(size);
106 }
107 
109  : size(siz), buffer(0), currentIdx(0)
110 {
111  if ( sizeof(G4double)*CHAR_BIT==64 )
112  {
114  }
115  else
116  {
118  }
119  Fill(size);
120 
121 }
122 
124 {
125  if ( sizeof(G4double)*CHAR_BIT==64 )
126  {
128  }
129  else
130  {
132  }
133 }
134 
135 void G4UniformRandPool::Resize(/*PoolSize_t*/ G4int newSize )
136 {
137  if ( newSize != size )
138  {
140  create_pool(buffer,newSize);
141  size=newSize;
142  currentIdx = 0;
143  }
144  currentIdx = 0;
145 }
146 
148 {
149  assert(howmany>0 && howmany <= size);
150 
151  // Fill buffer with random numbers
152  //
153  G4Random::getTheEngine()->flatArray(howmany,buffer);
154  currentIdx = 0;
155 }
156 
158 {
159  assert(rnds!=0 && howmany>0);
160 
161  // if ( howmany <= 0 ) return;
162  // We generate at max "size" numbers at once, and
163  // We do not want to use recursive calls (expensive).
164  // We need to deal with the case howmany>size
165  // So:
166  // how many times I need to get "size" numbers?
167 
168  const G4int maxcycles = howmany/size;
169 
170  // This is the rest
171  //
172  const G4int peel = howmany%size;
173  assert(peel<size);
174 
175  // Ok from now on I will get random numbers in group of "size"
176  // Note that if howmany<size maxcycles == 0
177  //
178  G4int cycle = 0;
179 
180  // Consider the case howmany>size, then maxcycles>=1
181  // and we will request at least "size" rng, so
182  // let's start with a fresh buffer of numbers if needed
183  //
184  if ( maxcycles>0 && currentIdx>0 )
185  {
186  assert(currentIdx<=size);
187  Fill(currentIdx);//<size?currentIdx:size);
188  }
189  for ( ; cycle < maxcycles ; ++cycle )
190  {
191  // We can use memcpy of std::copy, it turns out that the two are basically
192  // performance-wise equivalent (expected), since in my tests memcpy is a
193  // little bit faster, I use that
194  //
195  memcpy(rnds+(cycle*size),buffer,sizeof(G4double)*size );
196  // std::copy(buffer,buffer+size,rnds+(cycle*size));
197 
198  // Get a new set of numbers
199  //
200  Fill(size); // Now currentIdx is 0 again
201  }
202 
203  // If maxcycles>0 last think we did was to call Fill(size)
204  // so currentIdx == 0
205  // and it is guaranteed that peel<size, we have enough fresh random numbers
206  // but if maxcycles==0 currentIdx can be whatever, let's make sure we have
207  // enough fresh numbers
208  //
209  if (currentIdx + peel >= size)
210  {
212  }
213  memcpy(rnds+(cycle*size) , buffer+currentIdx , sizeof(G4double)*peel );
214  // std::copy(buffer+currentIdx,buffer+(currentIdx+peel), rnds+(cycle*size));
215 
216  // Advance index, we are done
217  //
218  currentIdx+=peel;
219  assert(currentIdx<=size);
220 }
221 
222 // Static interfaces implementing CLHEP methods
223 
224 namespace
225 {
226  G4ThreadLocal G4UniformRandPool* rndpool = 0;
227 }
228 
230 {
231  if ( rndpool == 0 )
232  {
233  rndpool = new G4UniformRandPool;
234  G4AutoDelete::Register(rndpool);
235  }
236  return rndpool->GetOne();
237 }
238 
240 {
241  if ( rndpool == 0 )
242  {
243  rndpool = new G4UniformRandPool;
244  G4AutoDelete::Register(rndpool);
245  }
246  rndpool->GetMany(rnds,(unsigned int)howmany);
247 }
void destroy_pool(G4double *&buffer)
static void flatArray(G4int howmany, G4double *rnds)
void Resize(G4int newSize)
void create_pool(G4double *&buffer, G4int ps)
#define buffer
Definition: xmlparse.cc:628
#define G4UNIFORMRANDPOOL_DEFAULT_POOLSIZE
#define G4ThreadLocal
Definition: tls.hh:69
void Register(T *inst)
Definition: G4AutoDelete.hh:65
static constexpr double ps
Definition: G4SIunits.hh:172
double G4double
Definition: G4Types.hh:76
static G4double flat()
void create_pool_align(G4double *&buffer, G4int ps)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
int G4int
Definition: G4Types.hh:78
void Fill(G4int howmany)
void destroy_pool_align(G4double *&buffer)
void GetMany(G4double *rnds, G4int howMany)