common.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. Copyright (c) 2018 tevador
  3. This file is part of RandomX.
  4. RandomX is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. RandomX is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with RandomX. If not, see<http://www.gnu.org/licenses/>.
  14. */
  15. #pragma once
  16. #include <cstdint>
  17. #include <iostream>
  18. namespace RandomX {
  19. using addr_t = uint32_t;
  20. constexpr int SeedSize = 32;
  21. constexpr int ResultSize = 32;
  22. constexpr int ArgonIterations = 3;
  23. constexpr uint32_t ArgonMemorySize = 262144; //KiB
  24. constexpr int ArgonLanes = 1;
  25. const char ArgonSalt[] = "Monero\x1A$";
  26. constexpr int ArgonSaltSize = sizeof(ArgonSalt) - 1;
  27. constexpr int CacheLineSize = 64;
  28. constexpr uint64_t DatasetSize = 4ULL * 1024 * 1024 * 1024; //4 GiB
  29. constexpr uint32_t CacheSize = ArgonMemorySize * 1024;
  30. constexpr int CacheBlockCount = CacheSize / CacheLineSize;
  31. constexpr int BlockExpansionRatio = DatasetSize / CacheSize;
  32. constexpr int DatasetBlockCount = BlockExpansionRatio * CacheBlockCount;
  33. constexpr int DatasetIterations = 10;
  34. #ifdef TRACE
  35. constexpr bool trace = true;
  36. #else
  37. constexpr bool trace = false;
  38. #endif
  39. union convertible_t {
  40. double f64;
  41. int64_t i64;
  42. uint64_t u64;
  43. int32_t i32;
  44. uint32_t u32;
  45. struct {
  46. int32_t i32lo;
  47. int32_t i32hi;
  48. };
  49. };
  50. struct fpu_reg_t {
  51. convertible_t lo;
  52. convertible_t hi;
  53. };
  54. constexpr int ProgramLength = 256;
  55. constexpr uint32_t InstructionCount = 1024;
  56. constexpr uint32_t ScratchpadSize = 2 * 1024 * 1024;
  57. constexpr uint32_t ScratchpadLength = ScratchpadSize / sizeof(convertible_t);
  58. constexpr uint32_t ScratchpadL1 = ScratchpadSize / 128 / sizeof(convertible_t);
  59. constexpr uint32_t ScratchpadL2 = ScratchpadSize / 8 / sizeof(convertible_t);
  60. constexpr uint32_t ScratchpadL3 = ScratchpadSize / sizeof(convertible_t);
  61. constexpr int ScratchpadL1Mask = (ScratchpadL1 - 1) * 8;
  62. constexpr int ScratchpadL2Mask = (ScratchpadL2 - 1) * 8;
  63. constexpr int ScratchpadL1Mask16 = (ScratchpadL1 / 2 - 1) * 16;
  64. constexpr int ScratchpadL2Mask16 = (ScratchpadL2 / 2 - 1) * 16;
  65. constexpr uint32_t TransformationCount = 90;
  66. constexpr int RegistersCount = 8;
  67. class Cache;
  68. inline int wrapInstr(int i) {
  69. return i % RandomX::ProgramLength;
  70. }
  71. class ILightClientAsyncWorker {
  72. public:
  73. virtual void prepareBlock(addr_t) = 0;
  74. virtual void prepareBlocks(void* out, uint32_t startBlock, uint32_t blockCount) = 0;
  75. virtual const uint64_t* getBlock(addr_t) = 0;
  76. virtual void getBlocks(void* out, uint32_t startBlock, uint32_t blockCount) = 0;
  77. virtual void sync() = 0;
  78. const Cache* getCache() {
  79. return cache;
  80. }
  81. protected:
  82. ILightClientAsyncWorker(const Cache* c) : cache(c) {}
  83. const Cache* cache;
  84. };
  85. union dataset_t {
  86. uint8_t* dataset;
  87. Cache* cache;
  88. ILightClientAsyncWorker* asyncWorker;
  89. };
  90. struct MemoryRegisters {
  91. addr_t mx, ma;
  92. dataset_t ds;
  93. };
  94. static_assert(sizeof(MemoryRegisters) == 2 * sizeof(addr_t) + sizeof(uintptr_t), "Invalid alignment of struct RandomX::MemoryRegisters");
  95. struct RegisterFile {
  96. convertible_t r[RegistersCount];
  97. fpu_reg_t f[RegistersCount / 2];
  98. fpu_reg_t g[RegistersCount / 2];
  99. fpu_reg_t a[RegistersCount / 2];
  100. };
  101. static_assert(sizeof(RegisterFile) == 256, "Invalid alignment of struct RandomX::RegisterFile");
  102. typedef void(*DatasetReadFunc)(addr_t, MemoryRegisters&, RegisterFile&);
  103. typedef void(*ProgramFunc)(RegisterFile&, MemoryRegisters&, convertible_t*, uint64_t);
  104. typedef bool(*Condition)(convertible_t&, convertible_t&);
  105. extern "C" {
  106. void executeProgram(RegisterFile&, MemoryRegisters&, convertible_t*, uint64_t);
  107. }
  108. }
  109. std::ostream& operator<<(std::ostream& os, const RandomX::RegisterFile& rf);