Advertisement
Kaelygon

Pseudo random numbers C++ Cuda

Nov 26th, 2023
1,339
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.53 KB | None | 0 0
  1.  
  2. //nvcc -g ./main.cu -O3 -lpthread -lcudart -o ./main -Xcompiler -rdynamic -lineinfo && ./main
  3. //
  4. //Generates pseudo random numbers. nvidia gtx 1080 and amd 5900x ./main | pv > /dev/zero # 2.8 GB/s
  5. //passes most dieharder tests
  6. //./main | dieharder -B -g 200 -a
  7. //
  8. //variation of ukaelEntropy https://github.com/Kaelygon/ukaelAudio/blob/main/ukaelH/kmath.h
  9.  
  10. #include <iostream>
  11. #include <vector>
  12. #include <thread>
  13. #include <fstream>
  14. #include <time.h>
  15.  
  16. __global__
  17. void kaelRandom(uint64_t *data, uint64_t dataCount) {
  18.     __uint64_t index = blockIdx.x * blockDim.x + threadIdx.x;
  19.     __uint64_t stride = blockDim.x * gridDim.x;
  20.  
  21.     for(uint ti=index;ti<dataCount;ti+=stride){
  22.         uint stId = ti;
  23.         uint ndId = ti+1==dataCount ? 0 : ti+1; //prevent array overflow
  24.  
  25.         data[stId] = (data[stId] >> 41) | (data[stId] << 23); // bit rotate rorw
  26.         data[stId] += data[ndId]*131 + 13238717; // shift and add
  27.         data[ndId] += data[stId]*129 + 13238689;
  28.     }
  29.  
  30. }
  31.  
  32. void seedTime(uint64_t *data, uint dataCount) {
  33.     for (uint64_t i = 0; i < dataCount; i++) {
  34.         data[i] = i * 60618691999346397ULL + 15940286172355421827ULL; // random lcg
  35.  
  36.         uint64_t timebuf = time(NULL); //entropy from time
  37.         data[i] ^= timebuf*i+timebuf;
  38.  
  39.         data[i] = (data[i] >> 41) | (data[i] << 23); // bit rotate rorw
  40.         data[i] += (data[i]<<2) + 13238717; //shift and add
  41.     }
  42. }
  43.  
  44. void seedZero(uint64_t *data, uint dataCount) {
  45.     for (uint64_t i = 0; i < dataCount; i++) {
  46.         data[i] = 0;
  47.     }
  48. }
  49.  
  50. int main() {
  51.    
  52.     const uint numBlocks = 512;
  53.     const uint blockSize = 512;
  54.     const uint bufSize = 2;
  55.  
  56.     uint64_t *dataArray[2];
  57.     uint chunkSize = 2048;
  58.     uint dataCount = chunkSize*blockSize*2; //2 numbers per thread
  59.     size_t dataSize = dataCount*sizeof(uint64_t);
  60.  
  61.     for(int bi=0;bi<bufSize;bi++){
  62.         cudaMallocManaged(&dataArray[bi], dataSize); // Allocate memory on the GPU
  63.     }
  64.  
  65.     //initialize to buffer
  66.     seedTime(dataArray[0], dataCount);
  67.     kaelRandom<<<numBlocks, blockSize>>>(dataArray[0], dataCount);
  68.  
  69.     std::vector<std::thread> writeThread;
  70.  
  71.     for(int i=0;true;i++){
  72.         cudaMemcpy(dataArray[1], dataArray[0], dataSize, cudaMemcpyDeviceToHost); //copy to buffer dataArray[1]
  73.         kaelRandom<<<numBlocks, blockSize>>>(dataArray[0], dataCount); //calculate random kernel function
  74.  
  75.         fwrite(dataArray[1], sizeof(uint64_t), dataCount, stdout); //write raw binary 64 while GPU is calculating
  76.  
  77.         cudaDeviceSynchronize(); // Wait for all threads to finish
  78.     }
  79.  
  80.     cudaFree(dataArray); // Free allocated memory on the GPU
  81.  
  82.     std::cout << "\nComputed: " << dataCount/2 << "\n";
  83.  
  84.     return 0;
  85. }
  86.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement