mirror of
https://git.wownero.com/wownero/RandomWOW.git
synced 2024-12-22 07:48:54 +00:00
Added performance simulation
This commit is contained in:
parent
8a5ead5ce3
commit
378d5def38
11
randomx.sln
11
randomx.sln
@ -25,6 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scratchpad-entropy", "vcxpr
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jit-performance", "vcxproj\jit-performance.vcxproj", "{535F2111-FA81-4C76-A354-EDD2F9AA00E3}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jit-performance", "vcxproj\jit-performance.vcxproj", "{535F2111-FA81-4C76-A354-EDD2F9AA00E3}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perf-simulation", "vcxproj\perf-simulation.vcxproj", "{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@ -113,6 +115,14 @@ Global
|
|||||||
{535F2111-FA81-4C76-A354-EDD2F9AA00E3}.Release|x64.Build.0 = Release|x64
|
{535F2111-FA81-4C76-A354-EDD2F9AA00E3}.Release|x64.Build.0 = Release|x64
|
||||||
{535F2111-FA81-4C76-A354-EDD2F9AA00E3}.Release|x86.ActiveCfg = Release|Win32
|
{535F2111-FA81-4C76-A354-EDD2F9AA00E3}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{535F2111-FA81-4C76-A354-EDD2F9AA00E3}.Release|x86.Build.0 = Release|Win32
|
{535F2111-FA81-4C76-A354-EDD2F9AA00E3}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Release|x64.Build.0 = Release|x64
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -127,6 +137,7 @@ Global
|
|||||||
{3E490DEC-1874-43AA-92DA-1AC57C217EAC} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
{3E490DEC-1874-43AA-92DA-1AC57C217EAC} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
||||||
{FF8BD408-AFD8-43C6-BE98-4D03B37E840B} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
{FF8BD408-AFD8-43C6-BE98-4D03B37E840B} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
||||||
{535F2111-FA81-4C76-A354-EDD2F9AA00E3} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
{535F2111-FA81-4C76-A354-EDD2F9AA00E3} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
||||||
|
{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2} = {4A4A689F-86AF-41C0-A974-1080506D0923}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {4EBC03DB-AE37-4141-8147-692F16E0ED02}
|
SolutionGuid = {4EBC03DB-AE37-4141-8147-692F16E0ED02}
|
||||||
|
645
src/tests/perf-simulation.cpp
Normal file
645
src/tests/perf-simulation.cpp
Normal file
@ -0,0 +1,645 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the copyright holder nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include "../common.hpp"
|
||||||
|
#include "../aes_hash.hpp"
|
||||||
|
#include "../program.hpp"
|
||||||
|
#include "../blake2/blake2.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
int analyze(randomx::Program& p);
|
||||||
|
int executeInOrder(randomx::Program& p, randomx::Program& original, bool print, int executionPorts, int memoryPorts, bool speculate, int pipeline);
|
||||||
|
int executeOutOfOrder(randomx::Program& p, randomx::Program& original, bool print, int executionPorts, int memoryPorts, bool speculate, int pipeline);
|
||||||
|
|
||||||
|
constexpr uint32_t DST_NOP = 0;
|
||||||
|
constexpr uint32_t DST_INT = 1;
|
||||||
|
constexpr uint32_t DST_FLT = 2;
|
||||||
|
constexpr uint32_t DST_MEM = 3;
|
||||||
|
constexpr uint32_t MASK_DST = 3;
|
||||||
|
|
||||||
|
constexpr uint32_t SRC_NOP = 0;
|
||||||
|
constexpr uint32_t SRC_INT = 4;
|
||||||
|
constexpr uint32_t SRC_FLT = 8;
|
||||||
|
constexpr uint32_t SRC_MEM = 12;
|
||||||
|
constexpr uint32_t MASK_SRC = 12;
|
||||||
|
|
||||||
|
constexpr uint32_t OP_CFROUND = 16;
|
||||||
|
constexpr uint32_t OP_SWAP = 32;
|
||||||
|
constexpr uint32_t OP_BRANCH = 48;
|
||||||
|
constexpr uint32_t MASK_EXT = 48;
|
||||||
|
|
||||||
|
constexpr uint32_t OP_FLOAT = 64;
|
||||||
|
constexpr uint32_t BRANCH_TARGET = 128;
|
||||||
|
|
||||||
|
//template<bool softAes>
|
||||||
|
void generate(randomx::Program& p, uint32_t nonce) {
|
||||||
|
alignas(16) uint64_t hash[8];
|
||||||
|
blake2b(hash, sizeof(hash), &nonce, sizeof(nonce), nullptr, 0);
|
||||||
|
fillAes1Rx4<false>((void*)hash, sizeof(p), &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(randomx::Instruction& instr, uint32_t mask, uint32_t prop) {
|
||||||
|
return (instr.opcode & mask) == prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(randomx::Instruction& instr, uint32_t prop) {
|
||||||
|
return (instr.opcode & prop) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int nonces, seed, executionPorts, memoryPorts, pipeline;
|
||||||
|
bool print, reorder, speculate;
|
||||||
|
readOption("--print", argc, argv, print);
|
||||||
|
readOption("--reorder", argc, argv, reorder);
|
||||||
|
readOption("--speculate", argc, argv, speculate);
|
||||||
|
readIntOption("--nonces", argc, argv, nonces, 1);
|
||||||
|
readIntOption("--seed", argc, argv, seed, 0);
|
||||||
|
readIntOption("--executionPorts", argc, argv, executionPorts, 4);
|
||||||
|
readIntOption("--memoryPorts", argc, argv, memoryPorts, 2);
|
||||||
|
readIntOption("--pipeline", argc, argv, pipeline, 3 + speculate);
|
||||||
|
randomx::Program p, original;
|
||||||
|
double totalCycles = 0.0;
|
||||||
|
double jumpCount = 0;
|
||||||
|
for (int i = 0; i < nonces; ++i) {
|
||||||
|
generate(original, i ^ seed);
|
||||||
|
memcpy(&p, &original, sizeof(p));
|
||||||
|
jumpCount += analyze(p);
|
||||||
|
totalCycles +=
|
||||||
|
reorder
|
||||||
|
?
|
||||||
|
executeOutOfOrder(p, original, print, executionPorts, memoryPorts, speculate, pipeline)
|
||||||
|
:
|
||||||
|
executeInOrder(p, original, print, executionPorts, memoryPorts, speculate, pipeline);
|
||||||
|
}
|
||||||
|
totalCycles /= nonces;
|
||||||
|
jumpCount /= nonces;
|
||||||
|
std::cout << "Execution took " << totalCycles << " cycles per program" << std::endl;
|
||||||
|
//std::cout << "Jump count: " << jumpCount << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int executeInOrder(randomx::Program& p, randomx::Program& original, bool print, int executionPorts, int memoryPorts, bool speculate, int pipeline) {
|
||||||
|
int cycle = pipeline - 1;
|
||||||
|
int index = 0;
|
||||||
|
int branchCount = 0;
|
||||||
|
int int_reg_ready[randomx::RegistersCount] = { 0 };
|
||||||
|
int flt_reg_ready[randomx::RegistersCount] = { 0 };
|
||||||
|
//each workgroup takes 1 or 2 cycles (2 cycles if any instruction has a memory operand)
|
||||||
|
while (index < RANDOMX_PROGRAM_SIZE) {
|
||||||
|
int memoryReads = 0;
|
||||||
|
int memoryAccesses = 0;
|
||||||
|
bool hasRound = false;
|
||||||
|
int workers = 0;
|
||||||
|
//std::cout << "-----------" << std::endl;
|
||||||
|
for (; workers < executionPorts && memoryAccesses < memoryPorts && index < RANDOMX_PROGRAM_SIZE; ++workers) {
|
||||||
|
auto& instr = p(index);
|
||||||
|
auto& origi = original(index);
|
||||||
|
origi.dst %= randomx::RegistersCount;
|
||||||
|
origi.src %= randomx::RegistersCount;
|
||||||
|
|
||||||
|
//check dependencies
|
||||||
|
if (has(instr, MASK_SRC, SRC_INT) && int_reg_ready[instr.src] > cycle)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (has(instr, MASK_SRC, SRC_MEM) && int_reg_ready[instr.src] > cycle)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_FLT) && flt_reg_ready[instr.dst] > cycle)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_INT) && int_reg_ready[instr.dst] > cycle)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (hasRound && has(instr, OP_FLOAT))
|
||||||
|
break;
|
||||||
|
|
||||||
|
//execute
|
||||||
|
index++;
|
||||||
|
|
||||||
|
if (has(instr, MASK_EXT, OP_BRANCH)) {
|
||||||
|
branchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_FLT))
|
||||||
|
flt_reg_ready[instr.dst] = cycle + 1;
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_INT))
|
||||||
|
int_reg_ready[instr.dst] = cycle + 1;
|
||||||
|
|
||||||
|
if (has(instr, MASK_EXT, OP_SWAP)) {
|
||||||
|
int_reg_ready[instr.src] = cycle + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_EXT, OP_CFROUND))
|
||||||
|
hasRound = true;
|
||||||
|
|
||||||
|
if (has(instr, MASK_SRC, SRC_MEM)) {
|
||||||
|
memoryReads++;
|
||||||
|
memoryAccesses++;
|
||||||
|
if (print)
|
||||||
|
std::cout << std::setw(2) << (cycle + 2) << ": " << origi;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (print)
|
||||||
|
std::cout << std::setw(2) << (cycle + 1) << ": " << origi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_MEM)) {
|
||||||
|
memoryAccesses++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//non-speculative execution must stall after branch
|
||||||
|
if (!speculate && has(instr, MASK_EXT, OP_BRANCH)) {
|
||||||
|
cycle += pipeline - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//std::cout << " workers: " << workers << std::endl;
|
||||||
|
cycle++;
|
||||||
|
if (memoryReads)
|
||||||
|
cycle++;
|
||||||
|
}
|
||||||
|
if (speculate) {
|
||||||
|
//account for mispredicted branches
|
||||||
|
int i = 0;
|
||||||
|
while (branchCount--) {
|
||||||
|
auto entropy = p.getEntropy(i / 8);
|
||||||
|
entropy >> (i % 8) * 8;
|
||||||
|
if ((entropy & 0xff) == 0) // 1/256 chance to flush the pipeline
|
||||||
|
cycle += pipeline - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int executeOutOfOrder(randomx::Program& p, randomx::Program& original, bool print, int executionPorts, int memoryPorts, bool speculate, int pipeline) {
|
||||||
|
int index = 0;
|
||||||
|
int busyExecutionPorts[RANDOMX_PROGRAM_SIZE] = { 0 };
|
||||||
|
int busyMemoryPorts[RANDOMX_PROGRAM_SIZE] = { 0 };
|
||||||
|
int int_reg_ready[randomx::RegistersCount] = { 0 };
|
||||||
|
int flt_reg_ready[randomx::RegistersCount] = { 0 };
|
||||||
|
int fprcReady = 0;
|
||||||
|
int lastBranch = 0;
|
||||||
|
int branchCount = 0;
|
||||||
|
for (; index < RANDOMX_PROGRAM_SIZE; ++index) {
|
||||||
|
auto& instr = p(index);
|
||||||
|
int retireCycle = pipeline - 1;
|
||||||
|
|
||||||
|
//non-speculative execution cannot reorder across branches
|
||||||
|
if (!speculate && !has(instr, MASK_EXT, OP_BRANCH))
|
||||||
|
retireCycle = std::max(lastBranch + pipeline - 1, retireCycle);
|
||||||
|
|
||||||
|
//check dependencies
|
||||||
|
if (has(instr, MASK_SRC, SRC_INT)) {
|
||||||
|
retireCycle = std::max(retireCycle, int_reg_ready[instr.src]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_SRC, SRC_MEM)) {
|
||||||
|
retireCycle = std::max(retireCycle, int_reg_ready[instr.src]);
|
||||||
|
//find free memory port
|
||||||
|
do {
|
||||||
|
retireCycle++;
|
||||||
|
} while (busyMemoryPorts[retireCycle - 1] >= memoryPorts);
|
||||||
|
busyMemoryPorts[retireCycle - 1]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_FLT)) {
|
||||||
|
retireCycle = std::max(retireCycle, flt_reg_ready[instr.dst]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_INT)) {
|
||||||
|
retireCycle = std::max(retireCycle, int_reg_ready[instr.dst]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//floating point operations depend on the fprc register
|
||||||
|
if (has(instr, OP_FLOAT))
|
||||||
|
retireCycle = std::max(retireCycle, fprcReady);
|
||||||
|
|
||||||
|
//execute
|
||||||
|
if (has(instr, MASK_DST, DST_MEM)) {
|
||||||
|
//find free memory port
|
||||||
|
do {
|
||||||
|
retireCycle++;
|
||||||
|
} while (busyMemoryPorts[retireCycle - 1] >= memoryPorts);
|
||||||
|
busyMemoryPorts[retireCycle - 1]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_FLT)) {
|
||||||
|
//find free execution port
|
||||||
|
do {
|
||||||
|
retireCycle++;
|
||||||
|
} while (busyExecutionPorts[retireCycle - 1] >= executionPorts);
|
||||||
|
busyExecutionPorts[retireCycle - 1]++;
|
||||||
|
flt_reg_ready[instr.dst] = retireCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_DST, DST_INT)) {
|
||||||
|
//find free execution port
|
||||||
|
do {
|
||||||
|
retireCycle++;
|
||||||
|
} while (busyExecutionPorts[retireCycle - 1] >= executionPorts);
|
||||||
|
busyExecutionPorts[retireCycle - 1]++;
|
||||||
|
int_reg_ready[instr.dst] = retireCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_EXT, OP_SWAP)) {
|
||||||
|
int_reg_ready[instr.src] = retireCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_EXT, OP_CFROUND)) {
|
||||||
|
do {
|
||||||
|
retireCycle++;
|
||||||
|
} while (busyExecutionPorts[retireCycle - 1] >= executionPorts);
|
||||||
|
busyExecutionPorts[retireCycle - 1]++;
|
||||||
|
fprcReady = retireCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has(instr, MASK_EXT, OP_BRANCH)) {
|
||||||
|
/*if (!speculate && instr.mod == 1) { //simulated predication
|
||||||
|
do {
|
||||||
|
retireCycle++;
|
||||||
|
} while (busyExecutionPorts[retireCycle - 1] >= executionPorts);
|
||||||
|
busyExecutionPorts[retireCycle - 1]++;
|
||||||
|
int_reg_ready[instr.dst] = retireCycle;
|
||||||
|
}*/
|
||||||
|
//else {
|
||||||
|
lastBranch = std::max(lastBranch, retireCycle);
|
||||||
|
branchCount++;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
//print
|
||||||
|
auto& origi = original(index);
|
||||||
|
origi.dst %= randomx::RegistersCount;
|
||||||
|
origi.src %= randomx::RegistersCount;
|
||||||
|
if (print) {
|
||||||
|
std::cout << std::setw(2) << retireCycle << ": " << origi;
|
||||||
|
if (has(instr, MASK_EXT, OP_BRANCH)) {
|
||||||
|
std::cout << " jump: " << (int)instr.mod << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int cycle = 0;
|
||||||
|
for (int i = 0; i < randomx::RegistersCount; ++i) {
|
||||||
|
cycle = std::max(cycle, int_reg_ready[i]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < randomx::RegistersCount; ++i) {
|
||||||
|
cycle = std::max(cycle, flt_reg_ready[i]);
|
||||||
|
}
|
||||||
|
if (speculate) {
|
||||||
|
//account for mispredicted branches
|
||||||
|
int i = 0;
|
||||||
|
while (branchCount--) {
|
||||||
|
auto entropy = p.getEntropy(i / 8);
|
||||||
|
entropy >> (i % 8) * 8;
|
||||||
|
if ((entropy & 0xff) == 0) // 1/256 chance to flush the pipeline
|
||||||
|
cycle += pipeline - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "../instruction_weights.hpp"
|
||||||
|
|
||||||
|
//old register selection
|
||||||
|
struct RegisterUsage {
|
||||||
|
int32_t lastUsed;
|
||||||
|
int32_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int getConditionRegister(RegisterUsage(®isterUsage)[randomx::RegistersCount]) {
|
||||||
|
int min = INT_MAX;
|
||||||
|
int minCount = 0;
|
||||||
|
int minIndex;
|
||||||
|
//prefer registers that have been used as a condition register fewer times
|
||||||
|
for (unsigned i = 0; i < randomx::RegistersCount; ++i) {
|
||||||
|
if (registerUsage[i].lastUsed < min || (registerUsage[i].lastUsed == min && registerUsage[i].count < minCount)) {
|
||||||
|
min = registerUsage[i].lastUsed;
|
||||||
|
minCount = registerUsage[i].count;
|
||||||
|
minIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
int analyze(randomx::Program& p) {
|
||||||
|
int jumpCount = 0;
|
||||||
|
RegisterUsage registerUsage[randomx::RegistersCount];
|
||||||
|
for (unsigned i = 0; i < randomx::RegistersCount; ++i) {
|
||||||
|
registerUsage[i].lastUsed = -1;
|
||||||
|
registerUsage[i].count = 0;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) {
|
||||||
|
auto& instr = p(i);
|
||||||
|
int opcode = instr.opcode;
|
||||||
|
instr.opcode = 0;
|
||||||
|
switch (opcode) {
|
||||||
|
CASE_REP(IADD_RS) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IADD_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
}
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(ISUB_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(ISUB_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
}
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IMUL_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IMUL_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
}
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IMULH_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IMULH_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
}
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(ISMULH_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(ISMULH_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
}
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IMUL_RCP) {
|
||||||
|
uint64_t divisor = instr.getImm32();
|
||||||
|
if (!randomx::isPowerOf2(divisor)) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(INEG_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IXOR_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IXOR_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
}
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IROR_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(IROL_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(ISWAP_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
if (instr.src != instr.dst) {
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
instr.opcode |= OP_SWAP;
|
||||||
|
registerUsage[instr.dst].lastUsed = i;
|
||||||
|
registerUsage[instr.src].lastUsed = i;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FSWAP_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FADD_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FADD_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FSUB_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FSUB_M) {
|
||||||
|
instr.dst = instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FSCAL_R) {
|
||||||
|
instr.dst = instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FMUL_R) {
|
||||||
|
instr.dst = 4 + instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FDIV_M) {
|
||||||
|
instr.dst = 4 + instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= SRC_MEM;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(FSQRT_R) {
|
||||||
|
instr.dst = 4 + instr.dst % randomx::RegisterCountFlt;
|
||||||
|
instr.opcode |= DST_FLT;
|
||||||
|
instr.opcode |= OP_FLOAT;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(CBRANCH) {
|
||||||
|
instr.opcode |= OP_BRANCH;
|
||||||
|
instr.opcode |= DST_INT;
|
||||||
|
//jump condition
|
||||||
|
//int reg = getConditionRegister(registerUsage);
|
||||||
|
int reg = instr.dst % randomx::RegistersCount;
|
||||||
|
int target = registerUsage[reg].lastUsed;
|
||||||
|
int offset = (i - target);
|
||||||
|
instr.mod = offset;
|
||||||
|
jumpCount += offset;
|
||||||
|
p(target + 1).opcode |= BRANCH_TARGET;
|
||||||
|
registerUsage[reg].count++;
|
||||||
|
instr.dst = reg;
|
||||||
|
//mark all registers as used
|
||||||
|
for (unsigned j = 0; j < randomx::RegistersCount; ++j) {
|
||||||
|
registerUsage[j].lastUsed = i;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(CFROUND) {
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
instr.opcode |= OP_CFROUND;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(ISTORE) {
|
||||||
|
instr.dst = instr.dst % randomx::RegistersCount;
|
||||||
|
instr.src = instr.src % randomx::RegistersCount;
|
||||||
|
instr.opcode |= SRC_INT;
|
||||||
|
instr.opcode |= DST_MEM;
|
||||||
|
if (instr.getModCond() < randomx::StoreL3Condition)
|
||||||
|
instr.imm32 = (instr.getModMem() ? randomx::ScratchpadL1Mask : randomx::ScratchpadL2Mask);
|
||||||
|
else
|
||||||
|
instr.imm32 &= randomx::ScratchpadL3Mask;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
CASE_REP(NOP) {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jumpCount;
|
||||||
|
}
|
128
vcxproj/perf-simulation.vcxproj
Normal file
128
vcxproj/perf-simulation.vcxproj
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>15.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{F1FC7AC0-2773-4A57-AFA7-56BB07216AA2}</ProjectGuid>
|
||||||
|
<RootNamespace>perfsimulation</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup />
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\src\tests\perf-simulation.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="randomx.vcxproj">
|
||||||
|
<Project>{3346a4ad-c438-4324-8b77-47a16452954b}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
22
vcxproj/perf-simulation.vcxproj.filters
Normal file
22
vcxproj/perf-simulation.vcxproj.filters
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\src\tests\perf-simulation.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user