Example #1
0
 std::string ToString(double value, size_t iCount, size_t fCount)
 {
     assert(iCount > 0);
     if(value > 0)
     {
         std::stringstream ss;
         ss << std::setprecision(fCount) << std::fixed << value;
         return ExpandToLeft(ss.str(), iCount + fCount + (fCount > 0 ? 1 : 0));
     }
     else
     {
         return ExpandToLeft("", iCount + fCount + 1);
     }
 }
Example #2
0
    std::string PerformanceMeasurerStorage::Report(bool sse42_, bool align, bool raw) const
    {
        struct Statistic
        {
            std::pair<Pm, Pm> simd;
            std::pair<Pm, Pm> base;
            Pm sse42;
            std::pair<Pm, Pm> sse2;
            std::pair<Pm, Pm> ssse3;
            std::pair<Pm, Pm> sse41;
            std::pair<Pm, Pm> avx2;
            std::pair<Pm, Pm> vsx;
        };
        typedef std::map<std::string, Statistic> StatisticMap;

        StatisticMap statistic;
        double timeMax = 0;
        size_t sizeMax = 8;
        bool sse2 = false, ssse3 = false, sse41 = false, sse42 = false, avx2 = false, vsx = false;
        for(Map::const_iterator it = _map.begin(); it != _map.end(); ++it)
        {
            const std::string & desc = it->second->Description();
            std::string name = FunctionShortName(desc);
            Statistic & s = statistic[name];
            if(desc.find("Simd::") == std::string::npos && desc.find("Simd") == 0)
            {
                if(Aligned(desc))
                    s.simd.first = *it->second;
                else
                    s.simd.second = *it->second;
            }
            if(desc.find("Simd::Base::") != std::string::npos)
            {
                if(Aligned(desc))
                    s.base.first = *it->second;
                else
                    s.base.second = *it->second;
            }
            if(desc.find("Simd::Sse2::") != std::string::npos || desc.find("Simd::Sse::") != std::string::npos)
            {
                if(Aligned(desc))
                    s.sse2.first = *it->second;
                else
                    s.sse2.second = *it->second;
                sse2 = true;
            }
            if(desc.find("Simd::Ssse3::") != std::string::npos)
            {
                if(Aligned(desc))
                    s.ssse3.first = *it->second;
                else
                    s.ssse3.second = *it->second;
                ssse3 = true;
            }
            if(desc.find("Simd::Sse41::") != std::string::npos)
            {
                if(Aligned(desc))
                    s.sse41.first = *it->second;
                else
                    s.sse41.second = *it->second;
                sse41 = true;
            }
            if(desc.find("Simd::Sse42::") != std::string::npos)
            {
                s.sse42 = *it->second;
                sse42 = true && sse42_;
            }
            if(desc.find("Simd::Avx2::") != std::string::npos || desc.find("Simd::Avx::") != std::string::npos)
            {
                if(Aligned(desc))
                    s.avx2.first = *it->second;
                else
                    s.avx2.second = *it->second;
                avx2 = true;
            }
            if(desc.find("Simd::Vsx::") != std::string::npos)
            {
                if(Aligned(desc))
                    s.vsx.first = *it->second;
                else
                    s.vsx.second = *it->second;
                vsx = true;
            }

            timeMax = std::max(timeMax, it->second->Average());
            sizeMax = std::max(name.size(), sizeMax);
        }

        const size_t ic = 1 + (size_t)::log10(std::max(timeMax*1000, 1.0));
        const size_t ir = 3;
        const size_t fc = 3;

        std::vector<std::string> statistics;
        for(StatisticMap::const_iterator it = statistic.begin(); it != statistic.end(); ++it)
        {
            const Statistic & s = it->second;
            std::stringstream ss;
            ss << ExpandToRight(it->first, sizeMax) << " | ";

            ss << ToString(s.simd.first.Average()*1000.0, ic, fc) << " ";
            ss << ToString(s.base.first.Average()*1000.0, ic, fc) << " ";
            if(sse2) ss << ToString(s.sse2.first.Average()*1000.0, ic, fc) << " ";
            if(ssse3) ss << ToString(s.ssse3.first.Average()*1000.0, ic, fc) << " ";
            if(sse41) ss << ToString(s.sse41.first.Average()*1000.0, ic, fc) << " ";
            if(sse42) ss << ToString(s.sse42.Average()*1000.0, ic, fc) << " ";
            if(avx2) ss << ToString(s.avx2.first.Average()*1000.0, ic, fc) << " ";
            if(vsx) ss << ToString(s.vsx.first.Average()*1000.0, ic, fc) << " ";
            ss << "| ";

            if(sse2 || ssse3 || sse41 || sse42 || avx2 || vsx)
            {
                if(sse2) ss << ToString(Relation(s.base.first, s.sse2.first), ir, fc) << " ";
                if(ssse3) ss << ToString(Relation(s.base.first, s.ssse3.first), ir, fc) << " ";
                if(sse41) ss << ToString(Relation(s.base.first, s.sse41.first), ir, fc) << " ";
                if(sse42) ss << ToString(Relation(s.base.first, s.sse42), ir, fc) << " ";
                if(avx2) ss << ToString(Relation(s.base.first, s.avx2.first), ir, fc) << " ";
                if(vsx) ss << ToString(Relation(s.base.first, s.vsx.first), ir, fc) << " ";
                ss << "| ";
            }

            if(sse2 && (ssse3 || sse41))
            {
                if(ssse3) ss << ToString(Relation(s.sse2.first, s.ssse3.first), ir, fc) << " ";
                if(sse41) ss << ToString(Relation(s.sse2.first, s.sse41.first), ir, fc) << " ";
                ss << "| ";
            }

            if((sse2 || ssse3 || sse41) && avx2)
            {
                if(sse2) ss << ToString(Relation(s.sse2.first, s.avx2.first), ir, fc) << " ";
                if(ssse3) ss << ToString(Relation(s.ssse3.first, s.avx2.first), ir, fc) << " ";
                if(sse41) ss << ToString(Relation(s.sse41.first, s.avx2.first), ir, fc) << " ";
                ss << "| ";
            }

            if(align)
            {
                ss << ToString(Relation(s.base.second, s.base.first), ir, fc) << " ";
                if(sse2) ss << ToString(Relation(s.sse2.second, s.sse2.first), ir, fc) << " ";
                if(ssse3) ss << ToString(Relation(s.ssse3.second, s.ssse3.first), ir, fc) << " ";
                if(sse41) ss << ToString(Relation(s.sse41.second, s.sse41.first), ir, fc) << " ";
                if(avx2) ss << ToString(Relation(s.avx2.second, s.avx2.first), ir, fc) << " ";
                if(vsx) ss << ToString(Relation(s.vsx.second, s.vsx.first), ir, fc) << " ";
                ss << "| ";
            }
            statistics.push_back(ss.str());
        }

        std::sort(statistics.begin(), statistics.end());

        std::stringstream header;
        header << ExpandToRight("Function", sizeMax) << " | ";

        header << ExpandToLeft("Simd", ic + fc + 1) << " ";
        header << ExpandToLeft("Base", ic + fc + 1) << " ";
        if(sse2) header << ExpandToLeft("Sse2", ic + fc + 1) << " ";
        if(ssse3) header << ExpandToLeft("Ssse3", ic + fc + 1) << " ";
        if(sse41) header << ExpandToLeft("Sse41", ic + fc + 1) << " ";
        if(sse42) header << ExpandToLeft("Sse42", ic + fc + 1) << " ";
        if(avx2) header << ExpandToLeft("Avx2", ic + fc + 1) << " ";
        if(vsx) header << ExpandToLeft("Vsx", ic + fc + 1) << " ";
        header << "| ";

        if(sse2 || ssse3 || sse41 || sse42 || avx2 || vsx)
        {
            if(sse2) header << ExpandToLeft("B/S2", ir + fc + 1) << " ";
            if(ssse3) header << ExpandToLeft("B/S3", ir + fc + 1) << " ";
            if(sse41) header << ExpandToLeft("B/S41", ir + fc + 1) << " ";
            if(sse42) header << ExpandToLeft("B/S42", ir + fc + 1) << " ";
            if(avx2) header << ExpandToLeft("B/A2", ir + fc + 1) << " ";
            if(vsx) header << ExpandToLeft("B/Vs", ir + fc + 1) << " ";
            header << "| ";
        }

        if(sse2 && (ssse3 || sse41))
        {
            if(ssse3) header << ExpandToLeft("S2/S3", ir + fc + 1) << " ";
            if(sse41) header << ExpandToLeft("S2/S41", ir + fc + 1) << " ";
            header << "| ";
        }

        if((sse2 || ssse3 || sse41) && avx2)
        {
            if(sse2) header << ExpandToLeft("S2/A2", ir + fc + 1) << " ";
            if(ssse3) header << ExpandToLeft("S3/A2", ir + fc + 1) << " ";
            if(sse41) header << ExpandToLeft("S41/A2", ir + fc + 1) << " ";
            header << "| ";
        }

        if(align)
        {
            header << ExpandToLeft("B:U/A", ir + fc + 1) << " ";
            if(sse2) header << ExpandToLeft("S2:U/A", ir + fc + 1) << " ";
            if(ssse3) header << ExpandToLeft("S3:U/A", ir + fc + 1) << " ";
            if(sse41) header << ExpandToLeft("S41:U/A", ir + fc + 1) << " ";
            if(avx2) header << ExpandToLeft("A2:U/A", ir + fc + 1) << " ";
            if(vsx) header << ExpandToLeft("Vs:U/A", ir + fc + 1) << " ";
            header << "| ";
        }

        std::stringstream separator;
        for(size_t i = 0; i < header.str().size(); ++i)
            separator << "-";

        std::stringstream report;

        if(raw)
        {
            report << std::endl << "Raw performance report:" << std::endl << std::endl;
            for(Map::const_iterator it = _map.begin(); it != _map.end(); ++it)
                report << it->second->Statistic() << std::endl;
        }

        report << std::endl << "Performance report:" << std::endl << std::endl;
        report << separator.str() << std::endl;
        report << header.str() << std::endl;
        report << separator.str() << std::endl;
        for(size_t i = 0; i < statistics.size(); ++i)
            report << statistics[i] << std::endl;
        report << separator.str() << std::endl;

        return report.str();
    }