Changeset 777

Show
Ignore:
Timestamp:
12/26/07 13:59:21 (14 years ago)
Author:
ppalmers
Message:

port freebob SSE optimized event encoding functions (untested)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/SConstruct

    r774 r777  
    285285                opt_flags.append ("-march=i686") 
    286286     
    287     if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse: 
     287    if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) \ 
     288       and build_host_supports_sse and env['ENABLE_OPTIMIZATIONS']: 
    288289        opt_flags.extend (["-msse", "-mfpmath=sse"]) 
    289290        env['USE_SSE'] = 1 
  • trunk/libffado/src/debugmodule/debugmodule.h

    r776 r777  
    5353#define MB_BUFFERSIZE       DEBUG_MAX_MESSAGE_LENGTH 
    5454 
    55 #define IMPLEMENT_BACKLOG 
     55#ifdef DEBUG 
     56 #define IMPLEMENT_BACKLOG 
     57#endif 
     58 
    5659#ifdef IMPLEMENT_BACKLOG 
    5760// the backlog is a similar buffer as the message buffer 
  • trunk/libffado/src/devicemanager.cpp

    r750 r777  
    8181DeviceManager::DeviceManager() 
    8282    : Control::Container("devicemanager") 
     83    , m_processorManager( new Streaming::StreamProcessorManager() ) 
    8384{ 
    8485    addOption(Util::OptionContainer::Option("slaveMode",false)); 
     
    8889DeviceManager::~DeviceManager() 
    8990{ 
     91    delete m_processorManager; 
     92 
    9093    for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
    9194          it != m_avDevices.end(); 
     
    98101    } 
    99102 
     103    for ( FunctorVectorIterator it = m_busreset_functors.begin(); 
     104          it != m_busreset_functors.end(); 
     105          ++it ) 
     106    { 
     107        delete *it; 
     108    } 
     109 
    100110    for ( Ieee1394ServiceVectorIterator it = m_1394Services.begin(); 
    101111          it != m_1394Services.end(); 
     
    104114        delete *it; 
    105115    } 
    106     for ( FunctorVectorIterator it = m_busreset_functors.begin(); 
    107           it != m_busreset_functors.end(); 
    108           ++it ) 
    109     { 
    110         delete *it; 
    111     } 
    112116} 
    113117 
    114118bool 
    115119DeviceManager::setThreadParameters(bool rt, int priority) { 
    116     if (!m_processorManager.setThreadParameters(rt, priority)) { 
     120    if (!m_processorManager->setThreadParameters(rt, priority)) { 
    117121        debugError("Could not set processor manager thread parameters\n"); 
    118122        return false; 
     
    419423 
    420424        debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n", 
    421                     m_processorManager.getNominalRate(), device); 
     425                    m_processorManager->getNominalRate(), device); 
    422426 
    423427        // Set the device's sampling rate to that requested 
    424428        // FIXME: does this really belong here?  If so we need to handle errors. 
    425         if (!device->setSamplingFrequency(m_processorManager.getNominalRate())) { 
     429        if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) { 
    426430            debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n", 
    427                         m_processorManager.getNominalRate(), device); 
     431                        m_processorManager->getNominalRate(), device); 
    428432 
    429433            // try again: 
    430             if (!device->setSamplingFrequency(m_processorManager.getNominalRate())) { 
    431                 debugFatal("Could not set sampling frequency to %d\n",m_processorManager.getNominalRate()); 
     434            if (!device->setSamplingFrequency(m_processorManager->getNominalRate())) { 
     435                debugFatal("Could not set sampling frequency to %d\n",m_processorManager->getNominalRate()); 
    432436                return false; 
    433437            } 
     
    438442 
    439443    // set the sync source 
    440     if (!m_processorManager.setSyncSource(getSyncSource())) { 
     444    if (!m_processorManager->setSyncSource(getSyncSource())) { 
    441445        debugWarning("Could not set processorManager sync source (%p)\n", 
    442446            getSyncSource()); 
     
    448452DeviceManager::prepareStreaming() 
    449453{ 
    450     if (!m_processorManager.prepare()) { 
     454    if (!m_processorManager->prepare()) { 
    451455        debugFatal("Could not prepare streaming...\n"); 
    452456        return false; 
     
    500504    } 
    501505 
    502     if(m_processorManager.start()) { 
     506    if(m_processorManager->start()) { 
    503507        return true; 
    504508    } else { 
     
    517521{ 
    518522    bool result = true; 
    519     m_processorManager.stop(); 
     523    m_processorManager->stop(); 
    520524 
    521525    // create the connections for all devices 
     
    550554bool 
    551555DeviceManager::waitForPeriod() { 
    552     if(m_processorManager.waitForPeriod()) { 
     556    if(m_processorManager->waitForPeriod()) { 
    553557        return true; 
    554558    } else { 
    555559        debugWarning("XRUN detected\n"); 
    556560        // do xrun recovery 
    557         m_processorManager.handleXrun(); 
     561        m_processorManager->handleXrun(); 
    558562        return false; 
    559563    } 
     
    562566bool 
    563567DeviceManager::setStreamingParams(unsigned int period, unsigned int rate, unsigned int nb_buffers) { 
    564     m_processorManager.setPeriodSize(period); 
    565     m_processorManager.setNominalRate(rate); 
    566     m_processorManager.setNbBuffers(nb_buffers); 
     568    m_processorManager->setPeriodSize(period); 
     569    m_processorManager->setNominalRate(rate); 
     570    m_processorManager->setNbBuffers(nb_buffers); 
    567571    return true; 
    568572} 
     
    756760    setDebugLevel(l); 
    757761    Control::Element::setVerboseLevel(l); 
    758     m_processorManager.setVerboseLevel(l); 
     762    m_processorManager->setVerboseLevel(l); 
    759763    for ( FFADODeviceVectorIterator it = m_avDevices.begin(); 
    760764          it != m_avDevices.end(); 
     
    810814void 
    811815DeviceManager::showStreamingInfo() { 
    812     m_processorManager.dumpInfo(); 
    813 } 
     816    m_processorManager->dumpInfo(); 
     817} 
  • trunk/libffado/src/devicemanager.h

    r750 r777  
    117117public: // FIXME: this should be better 
    118118    Streaming::StreamProcessorManager&  getStreamProcessorManager()  
    119         {return m_processorManager;}; 
     119        {return *m_processorManager;}; 
    120120private: 
    121     Streaming::StreamProcessorManager  m_processorManager; 
     121    Streaming::StreamProcessorManager*  m_processorManager; 
    122122protected: 
    123123    std::vector<std::string>          m_SpecStrings; 
  • trunk/libffado/src/libieee1394/ieee1394service.cpp

    r754 r777  
    102102    delete m_pCTRHelper; 
    103103    delete m_pIsoManager; 
    104     delete m_pTimeSource; 
    105104    stopRHThread(); 
    106105    for ( arm_handler_vec_t::iterator it = m_armHandlers.begin(); 
     
    116115    } 
    117116 
     117    delete m_pTimeSource; 
    118118    if ( m_handle ) { 
    119119        raw1394_destroy_handle( m_handle ); 
     
    352352uint64_t 
    353353Ieee1394Service::getCurrentTimeAsUsecs() { 
    354     assert(m_pTimeSource); 
    355     return m_pTimeSource->getCurrentTimeAsUsecs(); 
     354    if(m_pTimeSource) { 
     355        return m_pTimeSource->getCurrentTimeAsUsecs(); 
     356    } else { 
     357        debugError("No timesource!\n"); 
     358        return 0; 
     359    } 
    356360} 
    357361 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r776 r777  
    217217                poll_exit-poll_enter, iter_exit-iter_enter); 
    218218#else 
    219     // iterate itself blocks if nothing is available 
     219    // iterate blocks if no 1394 data is available 
    220220    // so poll'ing is not really necessary 
    221221    bool result = iterate(); 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r766 r777  
    2121 * 
    2222 */ 
     23#include "config.h" 
    2324 
    2425#include "AmdtpReceiveStreamProcessor.h" 
     
    250251} 
    251252 
     253#ifdef USE_SSE 
     254typedef float v4sf __attribute__ ((vector_size (16))); 
     255typedef int v4si __attribute__ ((vector_size (16))); 
     256typedef int v2si __attribute__ ((vector_size (8))); 
     257 
    252258int 
    253259AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort( 
     
    260266    target_event=(quadlet_t *)(data + p->getPosition()); 
    261267 
     268    static const float multiplier = 1.0f / (float)(0x7FFFFF); 
     269    static const float sse_multiplier[4] __attribute__((aligned(16))) = { 
     270            1.0f / (float)(0x7FFFFF), 
     271            1.0f / (float)(0x7FFFFF), 
     272            1.0f / (float)(0x7FFFFF), 
     273            1.0f / (float)(0x7FFFFF) 
     274    }; 
     275    unsigned int tmp[4]; 
     276 
    262277    switch(p->getDataType()) { 
    263278        default: 
     
    279294        case Port::E_Float: 
    280295            { 
    281                 const float multiplier = 1.0f / (float)(0x7FFFFF); 
    282296                float *buffer=(float *)(p->getBufferAddress()); 
    283297 
    284298                assert(nevents + offset <= p->getBufferSize()); 
    285299 
    286                 buffer+=offset; 
    287  
    288                 for(j = 0; j < nevents; j += 1) { // decode max nsamples 
    289  
     300                buffer += offset; 
     301                j = 0; 
     302                if(nevents > 3) { 
     303                    for(j = 0; j < nevents-3; j += 4) { 
     304                        tmp[0] = ntohl(*target_event); 
     305                        target_event += m_dimension; 
     306                        tmp[1] = ntohl(*target_event); 
     307                        target_event += m_dimension; 
     308                        tmp[2] = ntohl(*target_event); 
     309                        target_event += m_dimension; 
     310                        tmp[3] = ntohl(*target_event); 
     311                        target_event += m_dimension; 
     312                        asm("pslld $8, %[in2]\n\t" // sign extend 24th bit 
     313                                "pslld $8, %[in1]\n\t" 
     314                                "psrad $8, %[in2]\n\t" 
     315                                "psrad $8, %[in1]\n\t" 
     316                                "cvtpi2ps %[in2], %%xmm0\n\t" 
     317                                "movlhps %%xmm0, %%xmm0\n\t" 
     318                                "cvtpi2ps %[in1], %%xmm0\n\t" 
     319                                "mulps %[ssemult], %%xmm0\n\t" 
     320                                "movups %%xmm0, %[floatbuff]" 
     321                            : [floatbuff] "=m" (*(v4sf*)buffer) 
     322                            : [in1] "y" (*(v2si*)tmp), 
     323                        [in2] "y" (*(v2si*)(tmp+2)), 
     324                        [ssemult] "x" (*(v4sf*)sse_multiplier) 
     325                            : "xmm0"); 
     326                        buffer += 4; 
     327                    } 
     328                } 
     329                for(; j < nevents; ++j) { // decode max nsamples 
    290330                    unsigned int v = ntohl(*target_event) & 0x00FFFFFF; 
    291331                    // sign-extend highest bit of 24-bit int 
    292332                    int tmp = (int)(v << 8) / 256; 
    293  
    294333                    *buffer = tmp * multiplier; 
    295334 
     335                    buffer++; 
     336                    target_event += m_dimension; 
     337                } 
     338                asm volatile("emms"); 
     339                break; 
     340            } 
     341            break; 
     342    } 
     343 
     344    return 0; 
     345} 
     346 
     347#else 
     348 
     349int 
     350AmdtpReceiveStreamProcessor::decodeMBLAEventsToPort( 
     351                       AmdtpAudioPort *p, quadlet_t *data, 
     352                       unsigned int offset, unsigned int nevents) 
     353{ 
     354    unsigned int j=0; 
     355    quadlet_t *target_event; 
     356 
     357    target_event=(quadlet_t *)(data + p->getPosition()); 
     358 
     359    switch(p->getDataType()) { 
     360        default: 
     361        case Port::E_Int24: 
     362            { 
     363                quadlet_t *buffer=(quadlet_t *)(p->getBufferAddress()); 
     364 
     365                assert(nevents + offset <= p->getBufferSize()); 
     366 
     367                buffer+=offset; 
     368 
     369                for(j = 0; j < nevents; j += 1) { // decode max nsamples 
     370                    *(buffer)=(ntohl((*target_event) ) & 0x00FFFFFF); 
    296371                    buffer++; 
    297372                    target_event+=m_dimension; 
     
    299374            } 
    300375            break; 
     376        case Port::E_Float: 
     377            { 
     378                const float multiplier = 1.0f / (float)(0x7FFFFF); 
     379                float *buffer=(float *)(p->getBufferAddress()); 
     380 
     381                assert(nevents + offset <= p->getBufferSize()); 
     382 
     383                buffer+=offset; 
     384 
     385                for(j = 0; j < nevents; j += 1) { // decode max nsamples 
     386 
     387                    unsigned int v = ntohl(*target_event) & 0x00FFFFFF; 
     388                    // sign-extend highest bit of 24-bit int 
     389                    int tmp = (int)(v << 8) / 256; 
     390 
     391                    *buffer = tmp * multiplier; 
     392 
     393                    buffer++; 
     394                    target_event+=m_dimension; 
     395                } 
     396            } 
     397            break; 
    301398    } 
    302399 
    303400    return 0; 
    304401} 
     402#endif 
    305403} // end of namespace Streaming 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r776 r777  
    2222 */ 
    2323 
     24#include "config.h" 
    2425#include "AmdtpTransmitStreamProcessor.h" 
    2526#include "AmdtpPort.h" 
     
    99100    const int max_cycles_to_transmit_early = 2; 
    100101 
    101 try_block_of_frames: 
    102102    debugOutput ( DEBUG_LEVEL_ULTRA_VERBOSE, "Try for cycle %d\n", cycle ); 
    103103    // check whether the packet buffer has packets for us to send. 
     
    591591} 
    592592 
     593#ifdef USE_SSE 
     594typedef float v4sf __attribute__ ((vector_size (16))); 
     595typedef int v4si __attribute__ ((vector_size (16))); 
     596typedef int v2si __attribute__ ((vector_size (8))); 
     597 
     598int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
     599        unsigned int offset, unsigned int nevents ) 
     600{ 
     601    static const float sse_multiplier[4] __attribute__((aligned(16))) = { 
     602        (float)(0x7FFFFF00), 
     603        (float)(0x7FFFFF00), 
     604        (float)(0x7FFFFF00), 
     605        (float)(0x7FFFFF00) 
     606    }; 
     607 
     608    static const int sse_mask[4] __attribute__((aligned(16))) = { 
     609        0x40000000,  0x40000000,  0x40000000,  0x40000000 
     610    }; 
     611 
     612    unsigned int out[4]; 
     613 
     614    unsigned int j=0; 
     615    unsigned int read=0; 
     616 
     617    quadlet_t *target_event; 
     618 
     619    target_event= ( quadlet_t * ) ( data + p->getPosition() ); 
     620 
     621    switch ( p->getDataType() ) 
     622    { 
     623        default: 
     624        case Port::E_Int24: 
     625        { 
     626            quadlet_t *buffer= ( quadlet_t * ) ( p->getBufferAddress() ); 
     627 
     628            assert ( nevents + offset <= p->getBufferSize() ); 
     629 
     630            buffer+=offset; 
     631 
     632            for ( j = 0; j < nevents; j += 1 )   // decode max nsamples 
     633            { 
     634                *target_event = htonl ( ( * ( buffer ) & 0x00FFFFFF ) | 0x40000000 ); 
     635                buffer++; 
     636                target_event += m_dimension; 
     637            } 
     638        } 
     639        break; 
     640        case Port::E_Float: 
     641        { 
     642            const float multiplier = ( float ) ( 0x7FFFFF00 ); 
     643            float *buffer= ( float * ) ( p->getBufferAddress() ); 
     644 
     645            assert ( nevents + offset <= p->getBufferSize() ); 
     646 
     647            buffer+=offset; 
     648 
     649            j=0; 
     650            if(read>3) { 
     651                for (j = 0; j < read-3; j += 4) { 
     652                    asm("movups %[floatbuff], %%xmm0\n\t" 
     653                            "mulps %[ssemult], %%xmm0\n\t" 
     654                            "cvttps2pi %%xmm0, %[out1]\n\t" 
     655                            "movhlps %%xmm0, %%xmm0\n\t" 
     656                            "psrld $8, %[out1]\n\t" 
     657                            "cvttps2pi %%xmm0, %[out2]\n\t" 
     658                            "por %[mmxmask], %[out1]\n\t" 
     659                            "psrld $8, %[out2]\n\t" 
     660                            "por %[mmxmask], %[out2]\n\t" 
     661                        : [out1] "=&y" (*(v2si*)&out[0]), 
     662                    [out2] "=&y" (*(v2si*)&out[2]) 
     663                        : [floatbuff] "m" (*(v4sf*)buffer), 
     664                    [ssemult] "x" (*(v4sf*)sse_multiplier), 
     665                    [mmxmask] "y" (*(v2si*)sse_mask) 
     666                        : "xmm0"); 
     667                    buffer += 4; 
     668                    *target_event = htonl(out[0]); 
     669                    target_event += m_dimension; 
     670                    *target_event = htonl(out[1]); 
     671                    target_event += m_dimension; 
     672                    *target_event = htonl(out[2]); 
     673                    target_event += m_dimension; 
     674                    *target_event = htonl(out[3]); 
     675                    target_event += m_dimension; 
     676                } 
     677            } 
     678            for(; j < read; ++j) { 
     679            // don't care for overflow 
     680                float v = *buffer * multiplier;  // v: -231 .. 231 
     681                unsigned int tmp = (int)v; 
     682                *target_event = htonl((tmp >> 8) | 0x40000000); 
     683     
     684                buffer++; 
     685                target_event += m_dimension; 
     686            } 
     687 
     688            asm volatile("emms"); 
     689            break; 
     690        } 
     691        break; 
     692    } 
     693 
     694    return 0; 
     695} 
     696 
     697#else 
    593698 
    594699int AmdtpTransmitStreamProcessor::encodePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
     
    646751    return 0; 
    647752} 
     753#endif 
     754 
    648755int AmdtpTransmitStreamProcessor::encodeSilencePortToMBLAEvents ( AmdtpAudioPort *p, quadlet_t *data, 
    649756        unsigned int offset, unsigned int nevents )