Changeset 12423


Ignore:
Timestamp:
May 10, 2011, 3:50:54 AM (10 years ago)
Author:
jordan
Message:

(trunk libT) CPU optimization in peer-mgr.c's rechokeDownloads()

Instead of recalculating interesting pieces for each peer we loop through, calculate them just once into a bitfield and then reuse that bitfield inside the loop.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/peer-mgr.c

    r12421 r12423  
    27692769}
    27702770
    2771 /* do we still want this piece and does the peer have it? */
    2772 static bool
    2773 isPieceInteresting( const tr_torrent * tor, const tr_peer * peer, tr_piece_index_t index )
    2774 {
    2775     return ( !tor->info.pieces[index].dnd ) /* we want it */
    2776         && ( !tr_cpPieceIsComplete( &tor->completion, index ) )  /* we don't have it */
    2777         && ( tr_bitfieldHas( &peer->have, index ) ); /* peer has it */
    2778 }
    2779 
    27802771/* does this peer have any pieces that we want? */
    27812772static bool
    2782 isPeerInteresting( const tr_torrent * tor, const tr_peer * peer )
     2773isPeerInteresting( const tr_torrent  * const tor,
     2774                   const tr_bitfield * const interesting_pieces,
     2775                   const tr_peer     * const peer )
    27832776{
    27842777    tr_piece_index_t i, n;
    27852778
    2786     if ( tr_torrentIsSeed( tor ) )
    2787         return false;
    2788 
    2789     if( !tr_torrentIsPieceTransferAllowed( tor, TR_PEER_TO_CLIENT ) )
    2790         return false;
     2779    /* these cases should have already been handled by the calling code... */
     2780    assert( !tr_torrentIsSeed( tor ) );
     2781    assert( tr_torrentIsPieceTransferAllowed( tor, TR_PEER_TO_CLIENT ) );
     2782
     2783    if( peerIsSeed( peer ) )
     2784        return true;
    27912785
    27922786    for( i=0, n=tor->info.pieceCount; i<n; ++i )
    2793         if( isPieceInteresting( tor, peer, i ) )
     2787        if( tr_bitfieldHas( interesting_pieces, i ) && tr_bitfieldHas( &peer->have, i ) )
    27942788            return true;
    27952789
     
    29042898    t->maxPeers = maxPeers;
    29052899
    2906     /* decide WHICH peers to be interested in (based on their cancel-to-block ratio) */
    2907     for( i=0; i<peerCount; ++i )
    2908     {
    2909         tr_peer * peer = tr_ptrArrayNth( &t->peers, i );
    2910 
    2911         if( !isPeerInteresting( t->tor, peer ) )
     2900    if( peerCount > 0 )
     2901    {
     2902        const tr_torrent * const tor = t->tor;
     2903        const int n = tor->info.pieceCount;
     2904        tr_bitfield interesting_pieces = TR_BITFIELD_INIT;
     2905
     2906        /* build a bitfield of interesting pieces... */
     2907        tr_bitfieldConstruct( &interesting_pieces, n );
     2908        for( i=0; i<n; i++ )
     2909            if( !tor->info.pieces[i].dnd && !tr_cpPieceIsComplete( &tor->completion, i ) )
     2910                tr_bitfieldAdd( &interesting_pieces, i );
     2911
     2912        /* decide WHICH peers to be interested in (based on their cancel-to-block ratio) */
     2913        for( i=0; i<peerCount; ++i )
    29122914        {
    2913             tr_peerMsgsSetInterested( peer->msgs, false );
     2915            tr_peer * peer = tr_ptrArrayNth( &t->peers, i );
     2916
     2917            if( !isPeerInteresting( t->tor, &interesting_pieces, peer ) )
     2918            {
     2919                tr_peerMsgsSetInterested( peer->msgs, false );
     2920            }
     2921            else
     2922            {
     2923                tr_rechoke_state rechoke_state;
     2924                const int blocks = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
     2925                const int cancels = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
     2926
     2927                if( !blocks && !cancels )
     2928                    rechoke_state = RECHOKE_STATE_UNTESTED;
     2929                else if( !cancels )
     2930                    rechoke_state = RECHOKE_STATE_GOOD;
     2931                else if( !blocks )
     2932                    rechoke_state = RECHOKE_STATE_BAD;
     2933                else if( ( cancels * 10 ) < blocks )
     2934                    rechoke_state = RECHOKE_STATE_GOOD;
     2935                else
     2936                    rechoke_state = RECHOKE_STATE_BAD;
     2937
     2938                if( rechoke == NULL )
     2939                    rechoke = tr_new( struct tr_rechoke_info, peerCount );
     2940
     2941                 rechoke[rechoke_count].peer = peer;
     2942                 rechoke[rechoke_count].rechoke_state = rechoke_state;
     2943                 rechoke[rechoke_count].salt = tr_cryptoWeakRandInt( INT_MAX );
     2944                 rechoke_count++;
     2945            }
     2946
    29142947        }
    2915         else
    2916         {
    2917             tr_rechoke_state rechoke_state;
    2918             const int blocks = tr_historyGet( &peer->blocksSentToClient, now, CANCEL_HISTORY_SEC );
    2919             const int cancels = tr_historyGet( &peer->cancelsSentToPeer, now, CANCEL_HISTORY_SEC );
    2920 
    2921             if( !blocks && !cancels )
    2922                 rechoke_state = RECHOKE_STATE_UNTESTED;
    2923             else if( !cancels )
    2924                 rechoke_state = RECHOKE_STATE_GOOD;
    2925             else if( !blocks )
    2926                 rechoke_state = RECHOKE_STATE_BAD;
    2927             else if( ( cancels * 10 ) < blocks )
    2928                 rechoke_state = RECHOKE_STATE_GOOD;
    2929             else
    2930                 rechoke_state = RECHOKE_STATE_BAD;
    2931 
    2932             if( rechoke == NULL )
    2933                 rechoke = tr_new( struct tr_rechoke_info, peerCount );
    2934 
    2935              rechoke[rechoke_count].peer = peer;
    2936              rechoke[rechoke_count].rechoke_state = rechoke_state;
    2937              rechoke[rechoke_count].salt = tr_cryptoWeakRandInt( INT_MAX );
    2938              rechoke_count++;
    2939         }
    2940 
     2948
     2949        tr_bitfieldDestruct( &interesting_pieces );
    29412950    }
    29422951
     
    31483157                continue;
    31493158            rechokeUploads( t, now );
    3150             if( !tr_torrentIsSeed( tor ) )
     3159            if( !tr_torrentIsSeed( tor ) && tr_torrentIsPieceTransferAllowed( tor, TR_PEER_TO_CLIENT ) )
    31513160                rechokeDownloads( t );
    31523161        }
Note: See TracChangeset for help on using the changeset viewer.