fork(2) download
  1. // This software is in the public domain. Where that dedication is not
  2. // recognized, you are granted a perpetual, irrevocable license to copy
  3. // and modify this file as you see fit.
  4.  
  5. #include <cstdio>
  6. #include <cstdint>
  7.  
  8. void gen_octaves_of_value_noise_linear(
  9. uint32_t size,
  10. uint32_t seed,
  11. uint32_t octaves,
  12. float a,
  13. float *out)
  14. {
  15. if(octaves==0) return;
  16. if(octaves>31) octaves=31;
  17. while(size&(size-1)) size&=size-1;
  18. if(size==0) return;
  19. float b;
  20. uint32_t rnd=seed;
  21. while((size>>(octaves-1))==0) --octaves;
  22. for(uint32_t v=0;v<size;++v)
  23. for(uint32_t u=0;u<size;++u)
  24. out[v*size+u]=0.0f;
  25. b=1.0f;
  26. for(uint32_t i=0;i<octaves;++i)
  27. b=1.0f+a*b;
  28. b=1.0f/b;
  29. for(uint32_t i=0;i<octaves;++i)
  30. {
  31. uint32_t cursize=size>>(octaves-i-1);
  32. uint32_t step=1<<(octaves-i-1);
  33. // upscale step
  34. if(i>0)
  35. {
  36. uint32_t mask=cursize-1;
  37. for(uint32_t v=0;v<cursize;v+=2)
  38. for(uint32_t u=1;u<cursize;u+=2)
  39. out[v*step*size+u*step]=0.5f*(
  40. out[v*step*size+((u-1)&mask)*step]+
  41. out[v*step*size+((u+1)&mask)*step]);
  42. for(uint32_t v=1;v<cursize;v+=2)
  43. for(uint32_t u=0;u<cursize;++u)
  44. out[v*step*size+u*step]=0.5f*(
  45. out[((v-1)&mask)*step*size+u*step]+
  46. out[((v+1)&mask)*step*size+u*step]);
  47. }
  48. // white noise step
  49. for(uint32_t v=0;v<cursize;++v)
  50. {
  51. uint32_t index=v*step*size;
  52. for(uint32_t u=0;u<cursize;++u)
  53. {
  54. float t=float(rnd)*2.32830644e-10; // 2^-32
  55. rnd=rnd*1103515245ul+12345ul; // glibc LCG
  56. out[index]+=b*t;
  57. index+=step;
  58. }
  59. }
  60. b*=a;
  61. }
  62. }
  63.  
  64. uint64_t rdtsc()
  65. {
  66. uint64_t ret;
  67. asm volatile
  68. (
  69. "rdtsc"
  70. :"=A"(ret)
  71. );
  72. return ret;
  73. }
  74.  
  75. float image[1<<26];
  76.  
  77. int main()
  78. {
  79. for(uint32_t N=32;N<=8192;N*=2)
  80. {
  81. uint32_t octaves=7;
  82. uint64_t tacts=rdtsc();
  83. gen_octaves_of_value_noise_linear(N,0,7,0.73f,image);
  84. tacts=rdtsc()-tacts;
  85. printf("N=%d, time: %.0f tacts per texel.\n",N,double(tacts)/double(N*N));
  86. }
  87. for(uint32_t octaves=1;octaves<=16;++octaves)
  88. {
  89. uint32_t N=256;
  90. uint64_t tacts=rdtsc();
  91. gen_octaves_of_value_noise_linear(N,0,octaves,0.73f,image);
  92. tacts=rdtsc()-tacts;
  93. printf("octaves=%d, time: %.0f tacts per texel.\n",octaves,double(tacts)/double(N*N));
  94. }
  95. return 0;
  96. }
  97.  
Success #stdin #stdout 3.31s 265280KB
stdin
Standard input is empty
stdout
N=32, time: 80 tacts per texel.
N=64, time: 74 tacts per texel.
N=128, time: 75 tacts per texel.
N=256, time: 75 tacts per texel.
N=512, time: 78 tacts per texel.
N=1024, time: 79 tacts per texel.
N=2048, time: 80 tacts per texel.
N=4096, time: 82 tacts per texel.
N=8192, time: 86 tacts per texel.
octaves=1, time: 50 tacts per texel.
octaves=2, time: 65 tacts per texel.
octaves=3, time: 69 tacts per texel.
octaves=4, time: 70 tacts per texel.
octaves=5, time: 71 tacts per texel.
octaves=6, time: 71 tacts per texel.
octaves=7, time: 71 tacts per texel.
octaves=8, time: 71 tacts per texel.
octaves=9, time: 71 tacts per texel.
octaves=10, time: 71 tacts per texel.
octaves=11, time: 71 tacts per texel.
octaves=12, time: 71 tacts per texel.
octaves=13, time: 71 tacts per texel.
octaves=14, time: 71 tacts per texel.
octaves=15, time: 71 tacts per texel.
octaves=16, time: 71 tacts per texel.