예제 #1
0
파일: Common.cpp 프로젝트: blinds52/diskspd
bool Profile::Validate(bool fSingleSpec) const
{
    bool fOk = true;
    for (const auto& timeSpan : GetTimeSpans())
    {
        if (timeSpan.GetDisableAffinity() && timeSpan.GetAffinityAssignments().size() > 0)
        {
            fprintf(stderr, "ERROR: -n and -a parameters cannot be used together\n");
            fOk = false;
        }

        for (const auto& target : timeSpan.GetTargets())
        {
            const bool targetHasMultipleThreads = (timeSpan.GetThreadCount() > 1) || (target.GetThreadsPerFile() > 1);

            if (timeSpan.GetThreadCount() > 0 && target.GetThreadsPerFile() > 1)
            {
                fprintf(stderr, "ERROR: -F and -t parameters cannot be used together\n");
                fOk = false;
            }

            if (target.GetDisableAllCache() && target.GetDisableOSCache())
            {
                fprintf(stderr, "WARNING: -S is included in the effect of -h, specifying both is not required\n");
            }

            if (target.GetThroughputInBytesPerMillisecond() > 0 && timeSpan.GetCompletionRoutines())
            {
                fprintf(stderr, "ERROR: -g throughput control cannot be used with -x completion routines\n");
                fOk = false;
            }

            //  If burst size is specified think time must be specified and If think time is specified burst size should be non zero
            if ((target.GetThinkTime() == 0 && target.GetBurstSize() > 0) || (target.GetThinkTime() > 0 && target.GetBurstSize() == 0))
            {
                fprintf(stderr, "ERROR: need to specify -j<think time> with -i<burst size>\n");
                fOk = false;
            }

            // FIXME: we can no longer do this check, because the target no longer
            // contains a property that uniquely identifies the case where "-s" or <StrideSize>
            // was passed.  
#if 0
            if (target.GetUseRandomAccessPattern() && target.GetEnableCustomStrideSize())
            {
                fprintf(stderr, "WARNING: -s is ignored if -r is provided\n");
            }
#endif
            if (target.GetUseRandomAccessPattern())
            {
                if (target.GetThreadStrideInBytes() > 0)
                {
                    fprintf(stderr, "ERROR: -T conflicts with -r\n");
                    fOk = false;
                    // although ullThreadStride==0 is a valid value, it's interpreted as "not provided" for this warning
                }

                if (target.GetUseInterlockedSequential())
                {
                    fprintf(stderr, "ERROR: -si conflicts with -r\n");
                    fOk = false;
                }

                if (target.GetUseParallelAsyncIO())
                {
                    fprintf(stderr, "ERROR: -p conflicts with -r\n");
                    fOk = false;
                }
            }
            else
            {
                if (target.GetUseParallelAsyncIO() && target.GetRequestCount() == 1)
                {
                    fprintf(stderr, "WARNING: -p does not have effect unless outstanding I/O count (-o) is > 1\n");
                }

                if (timeSpan.GetRandSeed() > 0)
                {
                    fprintf(stderr, "WARNING: -z is ignored if -r is not provided\n");
                    // although ulRandSeed==0 is a valid value, it's interpreted as "not provided" for this warning
                }

                if (target.GetUseInterlockedSequential())
                {
                    if (target.GetThreadStrideInBytes() > 0)
                    {
                        fprintf(stderr, "ERROR: -si conflicts with -T\n");
                        fOk = false;
                    }

                    if (target.GetUseParallelAsyncIO())
                    {
                        fprintf(stderr, "ERROR: -si conflicts with -p\n");
                        fOk = false;
                    }

                    if (!targetHasMultipleThreads)
                    {
                        fprintf(stderr, "WARNING: single-threaded test, -si ignored\n");
                    }
                }
                else
                {
                    if (targetHasMultipleThreads && !target.GetThreadStrideInBytes())
                    {
                        fprintf(stderr, "WARNING: target access pattern will not be sequential, consider -si\n");
                    }

                    if (!targetHasMultipleThreads && target.GetThreadStrideInBytes())
                    {
                        fprintf(stderr, "ERROR: -T has no effect unless multiple threads per target are used\n");
                        fOk = false;
                    }
                }
            }

            if (target.GetRandomDataWriteBufferSize() > 0)
            {
                if (target.GetRandomDataWriteBufferSize() < target.GetBlockSizeInBytes())
                {
                    fprintf(stderr, "ERROR: custom write buffer (-Z) is smaller than the block size. Write buffer size: %I64u block size: %u\n",
                        target.GetRandomDataWriteBufferSize(),
                        target.GetBlockSizeInBytes());
                    fOk = false;
                }
            }

            // in the cases where there is only a single configuration specified for each target (e.g., cmdline),
            // currently there are no validations specific to individual targets (e.g., pre-existing files)
            // so we can stop validation now. this allows us to only warn/error once, as opposed to repeating
            // it for each target.
            if (fSingleSpec)
            {
                break;
            }
        }
    }
    return fOk;
}
예제 #2
0
bool Profile::Validate(bool fSingleSpec, SystemInformation *pSystem) const
{
    bool fOk = true;

    // Note that if no SystemInformation is provided, we do not verify the profile
    // v. the system content. This is used to limit code churn in the UT.

    if (pSystem != nullptr &&
        (pSystem->processorTopology._vProcessorGroupInformation.size() > 1 || pSystem->processorTopology._ulProcCount > 64))
    {
        fprintf(stderr, "WARNING: Complete CPU utilization cannot currently be gathered within DISKSPD for this system.\n"
            "         Use alternate mechanisms to gather this data such as perfmon/logman.\n"
            "         Active KGroups %u > 1 and/or processor count %u > 64.\n",
            (int) pSystem->processorTopology._vProcessorGroupInformation.size(),
            pSystem->processorTopology._ulProcCount);
    }

    if (GetTimeSpans().size() == 0)
    {
        fprintf(stderr, "ERROR: no timespans specified\n");
        fOk = false;
    }
    else
    {
        for (const auto& timeSpan : GetTimeSpans())
        {
            if (pSystem != nullptr)
            {
                for (const auto& Affinity : timeSpan.GetAffinityAssignments())
                {
                    if (Affinity.wGroup >= pSystem->processorTopology._vProcessorGroupInformation.size())
                    {
                        fprintf(stderr, "ERROR: affinity assignment to group %u; system only has %u groups\n",
                            Affinity.wGroup,
                            (int) pSystem->processorTopology._vProcessorGroupInformation.size());

                        fOk = false;

                    }
                    if (fOk && !pSystem->processorTopology._vProcessorGroupInformation[Affinity.wGroup].IsProcessorValid(Affinity.bProc))
                    {
                        fprintf(stderr, "ERROR: affinity assignment to group %u core %u not possible; group only has %u cores\n",
                            Affinity.wGroup,
                            Affinity.bProc,
                            pSystem->processorTopology._vProcessorGroupInformation[Affinity.wGroup]._maximumProcessorCount);

                        fOk = false;
                    }

                    if (fOk && !pSystem->processorTopology._vProcessorGroupInformation[Affinity.wGroup].IsProcessorActive(Affinity.bProc))
                    {
                        fprintf(stderr, "ERROR: affinity assignment to group %u core %u not possible; core is not active (current mask 0x%I64x)\n",
                            Affinity.wGroup,
                            Affinity.bProc,
                            pSystem->processorTopology._vProcessorGroupInformation[Affinity.wGroup]._activeProcessorMask);

                        fOk = false;
                    }
                }
            }

            if (timeSpan.GetDisableAffinity() && timeSpan.GetAffinityAssignments().size() > 0)
            {
                fprintf(stderr, "ERROR: -n and -a parameters cannot be used together\n");
                fOk = false;
            }

            for (const auto& target : timeSpan.GetTargets())
            {
                const bool targetHasMultipleThreads = (timeSpan.GetThreadCount() > 1) || (target.GetThreadsPerFile() > 1);

                if (timeSpan.GetThreadCount() > 0 && target.GetThreadsPerFile() > 1)
                {
                    fprintf(stderr, "ERROR: -F and -t parameters cannot be used together\n");
                    fOk = false;
                }

                if (target.GetThroughputInBytesPerMillisecond() > 0 && timeSpan.GetCompletionRoutines())
                {
                    fprintf(stderr, "ERROR: -g throughput control cannot be used with -x completion routines\n");
                    fOk = false;
                }

                //  If burst size is specified think time must be specified and If think time is specified burst size should be non zero
                if ((target.GetThinkTime() == 0 && target.GetBurstSize() > 0) || (target.GetThinkTime() > 0 && target.GetBurstSize() == 0))
                {
                    fprintf(stderr, "ERROR: need to specify -j<think time> with -i<burst size>\n");
                    fOk = false;
                }

                // FIXME: we can no longer do this check, because the target no longer
                // contains a property that uniquely identifies the case where "-s" or <StrideSize>
                // was passed.  
#if 0
                if (target.GetUseRandomAccessPattern() && target.GetEnableCustomStrideSize())
                {
                    fprintf(stderr, "WARNING: -s is ignored if -r is provided\n");
                }
#endif
                if (target.GetUseRandomAccessPattern())
                {
                    if (target.GetThreadStrideInBytes() > 0)
                    {
                        fprintf(stderr, "ERROR: -T conflicts with -r\n");
                        fOk = false;
                        // although ullThreadStride==0 is a valid value, it's interpreted as "not provided" for this warning
                    }

                    if (target.GetUseInterlockedSequential())
                    {
                        fprintf(stderr, "ERROR: -si conflicts with -r\n");
                        fOk = false;
                    }

                    if (target.GetUseParallelAsyncIO())
                    {
                        fprintf(stderr, "ERROR: -p conflicts with -r\n");
                        fOk = false;
                    }
                }
                else
                {
                    if (target.GetUseParallelAsyncIO() && target.GetRequestCount() == 1)
                    {
                        fprintf(stderr, "WARNING: -p does not have effect unless outstanding I/O count (-o) is > 1\n");
                    }

                    if (timeSpan.GetRandSeed() > 0)
                    {
                        fprintf(stderr, "WARNING: -z is ignored if -r is not provided\n");
                        // although ulRandSeed==0 is a valid value, it's interpreted as "not provided" for this warning
                    }

                    if (target.GetUseInterlockedSequential())
                    {
                        if (target.GetThreadStrideInBytes() > 0)
                        {
                            fprintf(stderr, "ERROR: -si conflicts with -T\n");
                            fOk = false;
                        }

                        if (target.GetUseParallelAsyncIO())
                        {
                            fprintf(stderr, "ERROR: -si conflicts with -p\n");
                            fOk = false;
                        }

                        if (!targetHasMultipleThreads)
                        {
                            fprintf(stderr, "WARNING: single-threaded test, -si ignored\n");
                        }
                    }
                    else
                    {
                        if (targetHasMultipleThreads && !target.GetThreadStrideInBytes())
                        {
                            fprintf(stderr, "WARNING: target access pattern will not be sequential, consider -si\n");
                        }

                        if (!targetHasMultipleThreads && target.GetThreadStrideInBytes())
                        {
                            fprintf(stderr, "ERROR: -T has no effect unless multiple threads per target are used\n");
                            fOk = false;
                        }
                    }
                }

                if (target.GetRandomDataWriteBufferSize() > 0)
                {
                    if (target.GetRandomDataWriteBufferSize() < target.GetBlockSizeInBytes())
                    {
                        fprintf(stderr, "ERROR: custom write buffer (-Z) is smaller than the block size. Write buffer size: %I64u block size: %u\n",
                            target.GetRandomDataWriteBufferSize(),
                            target.GetBlockSizeInBytes());
                        fOk = false;
                    }
                }

                // in the cases where there is only a single configuration specified for each target (e.g., cmdline),
                // currently there are no validations specific to individual targets (e.g., pre-existing files)
                // so we can stop validation now. this allows us to only warn/error once, as opposed to repeating
                // it for each target.
                if (fSingleSpec)
                {
                    break;
                }
            }
        }
    }

    return fOk;
}