Path: blob/main/test/benchmark/benchmark_memcpy.cpp
4133 views
// Copyright 2017 The Emscripten Authors. All rights reserved.1// Emscripten is available under two separate licenses, the MIT license and the2// University of Illinois/NCSA Open Source License. Both these licenses can be3// found in the LICENSE file.45#include <string.h>6#include <stdio.h>7#include <stdlib.h>8#include <vector>9#include <iostream>10#include <algorithm>1112#ifdef WIN3213#include <Windows.h>14#define aligned_alloc(align, size) _aligned_malloc((size), (align))15#endif1617#ifdef __EMSCRIPTEN__18#include <emscripten/emscripten.h>19#endif2021#include "tick.h"2223char dst[1024*1024*64+16] = {};24char src[1024*1024*64+16] = {};2526uint8_t resultCheckSum = 0;2728void __attribute__((noinline)) test_memcpy(int numTimes, int copySize)29{30for(int i = 0; i < numTimes - 8; i += 8)31{32memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];33memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];34memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];35memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];36memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];37memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];38memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];39memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];40}41numTimes &= 15;42for(int i = 0; i < numTimes; ++i)43{44memcpy(dst, src, copySize); resultCheckSum += dst[copySize >> 1];45}46}4748std::vector<int> copySizes;49std::vector<double> results;5051std::vector<int> testCases;5253double totalTimeSecs = 0.0;5455void test_case(int copySize)56{57const int minimumCopyBytes = 1024*1024*64;5859int numTimes = (minimumCopyBytes + copySize-1) / copySize;60if (numTimes < 8) numTimes = 8;6162tick_t bestResult = 1e9;6364#ifndef NUM_TRIALS65#define NUM_TRIALS 566#endif6768for(int i = 0; i < NUM_TRIALS; ++i)69{70double t0 = tick();71test_memcpy(numTimes, copySize);72double t1 = tick();73if (t1 - t0 < bestResult) bestResult = t1 - t0;74totalTimeSecs += (double)(t1 - t0) / ticks_per_sec();75}76unsigned long long totalBytesTransferred = numTimes * copySize;7778copySizes.push_back(copySize);7980tick_t ticksElapsed = bestResult;81if (ticksElapsed > 0)82{83double seconds = (double)ticksElapsed / ticks_per_sec();84double bytesPerSecond = totalBytesTransferred / seconds;85double mbytesPerSecond = bytesPerSecond / (1024.0*1024.0);86results.push_back(mbytesPerSecond);87}88else89{90results.push_back(0.0);91}92}9394void print_results()95{96std::cout << "Test cases: " << std::endl;97for(size_t i = 0; i < copySizes.size(); ++i)98{99std::cout << copySizes[i];100if (i != copySizes.size()-1) std::cout << ", ";101else std::cout << std::endl;102if (i % 10 == 9) std::cout << std::endl;103}104std::cout << std::endl;105std::cout << std::endl;106std::cout << std::endl;107std::cout << "Test results: " << std::endl;108for(size_t i = 0; i < results.size(); ++i)109{110std::cout << results[i];111if (i != results.size()-1) std::cout << ", ";112else std::cout << std::endl;113if (i % 10 == 9) std::cout << std::endl;114}115116std::cout << "Result checksum: " << (int)resultCheckSum << std::endl;117std::cout << "Total time: " << totalTimeSecs << std::endl;118}119120int numDone = 0;121122void run_one()123{124std::cout << (numDone+1) << "/" << (numDone+testCases.size()) << std::endl;125++numDone;126127int copySize = testCases.front();128testCases.erase(testCases.begin());129test_case(copySize);130}131132#ifdef __EMSCRIPTEN__133void main_loop()134{135if (!testCases.empty())136{137run_one();138}139else140{141emscripten_cancel_main_loop();142print_results();143}144}145#endif146147#ifndef MAX_COPY148#define MAX_COPY 32*1024*1024149#endif150151#ifndef MIN_COPY152#define MIN_COPY 1153#endif154155int main()156{157for(int copySizeI = MIN_COPY; copySizeI < MAX_COPY; copySizeI <<= 1)158for(int copySizeJ = 1; copySizeJ <= copySizeI; copySizeJ <<= 1)159{160testCases.push_back(copySizeI | copySizeJ);161}162163std::sort(testCases.begin(), testCases.end());164#if defined(__EMSCRIPTEN__) && !defined(BUILD_FOR_SHELL)165emscripten_set_main_loop(main_loop, 0, 0);166#else167while(!testCases.empty()) run_one();168print_results();169#endif170}171172173