Problem mit Nutzung von AVX Compileroption in VS 2012 (C++)



  • Bei der Nutzung von AVX in den Compileroptionen bekomme ich bei folgendem Programm bereits im Konstruktor eine illegal instruction exception. Schalte ich die Nutzung von AVX aus, funktioniert alles. Mit VS 2010 funktioniert es auch. Hat jemand eine Idee, was ich falsch mache? Die alignments habe ich eingefügt damit ich die Daten auf 256bit Grenzen bekomme.

    Plattform ist:
    Betriebssystemname Microsoft Windows 7 Enterprise
    Version 6.1.7601 Service Pack 1 Build 7601
    Betriebssystemhersteller Microsoft Corporation
    Systemtyp x64-basierter PC
    Prozessor Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz, 2667 MHz, 2 Kern(e), 4 logische(r) Prozessor(en)

    performanceCounter.h

    #pragma once
    
    _declspec(align(32)) class PerformanceCounter
    {
    public:
        PerformanceCounter(void);
        virtual ~PerformanceCounter(void);
    
        double getCounterResolutionInCountsPerSec() const;
    
        /// how many measurements can be done. if exceeded an exception will be thrown
        virtual int getMaxNumberOfTimings(void) = 0;
        /// get the initial measurement and reset the counter for the number of measurements
        virtual void startMeasurement(void) = 0;
        /// get a new counter measurement, incrementing the number of total measurements done
        virtual void queryCounter(void) = 0;
        virtual double getDeltaInSeconds(unsigned int startPos, unsigned int endPos) = 0;
    
    protected:
        void setPerformanceResolution(const double& res);
    
    private:
        _declspec(align(32)) double resolution;
    };
    

    PerformanceCounter.cpp

    #include "PerformanceCounter.h"
    
    PerformanceCounter::~PerformanceCounter(void)
    {
    }
    
    PerformanceCounter::PerformanceCounter() : resolution(double(0.0))
    {
    }
    
    double PerformanceCounter::getCounterResolutionInCountsPerSec() const
    {
        return resolution;
    }
    
    void PerformanceCounter::setPerformanceResolution(const double& res)
    {
        resolution = res;
    }
    

    PerformanceCounterClock.h

    #pragma once
    #include "performancecounter.h"
    #include <time.h>
    #include <vector>
    
    using std::vector;
    
    _declspec(align(32)) class PerformanceCounterClock : public PerformanceCounter
    {
    public:
        PerformanceCounterClock(void);
        virtual ~PerformanceCounterClock(void);
    
        int getMaxNumberOfTimings(void);
        /// get initial counting value
        void startMeasurement(void);
        void queryCounter(void);
        double getDeltaInSeconds(unsigned int startPos, unsigned int endPos);
    private:
        _declspec(align(32)) vector<unsigned int> timings;
        _declspec(align(32)) unsigned int timingsIdx;
    };
    

    PerformanceCounterClock.cpp

    #include "PerformanceCounterClock.h"
    #include <exception>
    
    const int maxNumberOfTimings = 32;
    
    PerformanceCounterClock::PerformanceCounterClock()
    { 
        setPerformanceResolution((double)CLOCKS_PER_SEC);
    
        timings.resize(maxNumberOfTimings, 0);
    }
    
    PerformanceCounterClock::~PerformanceCounterClock(void)
    {
    }
    
    int PerformanceCounterClock::getMaxNumberOfTimings(void)
    {
        return maxNumberOfTimings-1;
    }
    
    void PerformanceCounterClock::startMeasurement(void)
    {
        timings[0] = clock();
        timingsIdx = 1; // set counting bucket index for next measurement
    }
    
    void PerformanceCounterClock::queryCounter(void)
    {
        if (timingsIdx < maxNumberOfTimings)
        {
            timings[timingsIdx++] = clock();
        }
        else
        {
            throw std::exception("PerformanceCounterWin32::queryCounter() counting buckets exhausted");
        }
    }
    
    double PerformanceCounterClock::getDeltaInSeconds(unsigned int startPos, unsigned int endPos)
    {
        if ( startPos < endPos && startPos >= 0
            && endPos < timingsIdx )
        {
            return (double(timings[endPos])-double(timings[startPos]))/getCounterResolutionInCountsPerSec();
        }
        else
        {
            throw std::exception("PerformanceCounterWin32::getDeltaInSeconds() parameter epic fail");
        }
    }
    

    testprogramm testmain.cpp

    #include <iostream>
    #include "PerformanceCounterClock.h"
    
    using namespace std;
    
    int main()
    {
    	_declspec(align(32)) PerformanceCounterClock perfCnt;
    
    	perfCnt.startMeasurement();
    	cout << "Measurement started" << endl;
    	perfCnt.queryCounter();
    
    	cout << "time used was" << perfCnt.getDeltaInSeconds(0,1);
    
    	return 0;
    }
    

    Befehlszeile:

    /GS /W3 /Zc:wchar_t /I"C:\work\learning\PerformanceMeasurement\PerformanceMeasurement" /Zi /Gm /Od /Fd"x64\Debug\vc110.pdb" /fp:precise /Zp16 /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /arch:AVX /Gd /MTd /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Test.pch"
    

    Für den Linker:

    /OUT:"C:\work\learning\PerformanceMeasurement\x64\Debug\Test.exe" /MANIFEST /NXCOMPAT /PDB:"C:\work\learning\PerformanceMeasurement\x64\Debug\Test.pdb" /DYNAMICBASE "PerformanceCounter.obj" "PerformanceCounterClock.obj" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"C:\work\learning\PerformanceMeasurement\x64\Debug\Test.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Test.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\work\learning\PerformanceMeasurement\PerformanceMeasurement\Debug" /TLBID:1
    


  • Hallo,

    ich kann in der Intel-Spezifikation für deinen Prozessor nicht entdecken, dass AVX überhaupt unterstützt wird, damit wäre für mich eine "illegal instruction exception" erklärbar...

    MfG,

    Probe-Nutzer



  • ... ich hatte mich verlesen. Vielen Dank für den Hinweis. Dann ist das ja erklärbar und völlig richtiges Verhalten. Blöd nur, dass beim compilieren für x64 SSE als Option ignoriert wird.


Anmelden zum Antworten