디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

약속한 소스코드 ( aligned / unaligned )

codesafer갤로그로 이동합니다. 2016.04.11 13:33:06
조회 1888 추천 25 댓글 7
														

소스 코드 한장으로 합쳤다.


//=============================================================================

// performance.h --------------------------------------------------------------


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <algorithm>


#define CSTR    // constructor place holder

#define DSTR    // destructor place holder

#define _____   // place holder


using   i8  = char;

using   u8  = unsigned char;

using   i16 = short;

using   u16 = unsigned short;

using   i32 = int;

using   i64 = long long;

using   u32 = unsigned int;

using   u64 = unsigned long long;

using   f32 = float;

using   f64 = double;


#ifdef _MSC_VER

#include <intrin.h>

#else

#include <x86intrin.h>

#define CHAR_BIT 8

#endif


#define SYS_BITS    ( sizeof( size_t ) * CHAR_BIT )


//-----------------------------------------------------------------------------


class                           RUNNER

{

private:

    const   char*               function_name;

    u64                         elapsed;


protected:

    bool                        is_success;


public:

    CSTR                        RUNNER

        (

            const char* function_name,

            void( *on_pre )( ),

            void( *on_run )( ),

            bool( *on_post )( )

            )

        : function_name( function_name )

        , on_pre( on_pre )

        , on_run( on_run )

        , on_post( on_post )

    {

        init();

    }

    DSTR    virtual            ~RUNNER()

    {};


    virtual void                init()

    {

        elapsed = -1;

        is_success = on_run != NULL;

    }


    void( *on_pre )( );

    void( *on_run )( );

    bool( *on_post )( );


    void                        check()

    {

        if( !on_run )

            return;

        if( on_pre )

            on_pre();


        u64     begin = __rdtsc();

        on_run();

        u64     duration = __rdtsc() - begin;

        elapsed = std::min( elapsed, duration );


        if( on_post )

            is_success &= on_post();

    }

    const   auto                set_length( const char* str, const size_t size )

    {

        static  char    temp[ 80 ];

        size_t          index;

        for( index = 0; str[ index ]; ++index ) temp[ index ] = str[ index ];

        for( ; index < size; ++index ) temp[ index ] = ' ';

        temp[ index ] = 0;

        return  temp;

    }

    const   auto                report()

    {

        const   char* judge_strings[] = { " FAILED        ", "        PASSED " };

        static  char temp[ 80 ];

        sprintf( temp, "[%s] %s llu clocks", judge_strings[ is_success ],

                 set_length( function_name, 20 ), elapsed );

        return  temp;

    }

    const   auto                elapsed_clocks()

    {

        return  elapsed;

    }

    const   auto                name()

    {

        return  function_name;

    }


};

//-----------------------------------------------------------------------------


#include <vector>

template < size_t REPEAT_COUNT = 1 >

class                           BENCH

{

private:

    std::vector< RUNNER* >      runner_list;


public:

    CSTR                        BENCH()

    {};

    DSTR                       ~BENCH()

    {};


    void                        add( RUNNER* runner )

    {

        runner_list.push_back( runner );

    }


    void                        run()

    {

        if( runner_list.size() == 0 ) return;

        printf( "< %d bits > %d trials", (int)SYS_BITS, (int)REPEAT_COUNT );

        puts( "" );

        puts( "-------------------------------------------------------------" );

        puts( "|  CHECKER      | Function  name      |   minimum  clocks   |" );

        puts( "-------------------------------------------------------------" );

        u64 min_value = -1;

        u64 max_value = 0;

        u32 min_index = 0;

        u32 max_index = 0;

        for( u32 test_case = 0; test_case < runner_list.size(); ++test_case )

        {

            runner_list[ test_case ]->init();

            for( u32 test_count = 0; test_count < REPEAT_COUNT; ++test_count )

                runner_list[ test_case ]->check();

            puts( runner_list[ test_case ]->report() );

            if( min_value > runner_list[ test_case ]->elapsed_clocks() )

            {

                min_index = test_case;

                min_value = runner_list[ test_case ]->elapsed_clocks();

            }

            if( max_value < runner_list[ test_case ]->elapsed_clocks() )

            {

                max_index = test_case;

                max_value = runner_list[ test_case ]->elapsed_clocks();

            }

        }

        puts( "-------------------------------------------------------------" );

        printf( "Winner is %s  ( %.2f times faster than loooser )",

                runner_list[ min_index ]->name(),

                float( runner_list[ max_index ]->elapsed_clocks() ) /

                runner_list[ min_index ]->elapsed_clocks() );

        puts( "" );

    }

};

//-----------------------------------------------------------------------------


#define COOL_FUN( function_name, ... )

    new RUNNER( #function_name, nil, []{ function_name(__VA_ARGS__); }, nil )


#define SO_FUN( pre, function_name, ... )

    new RUNNER( #function_name, pre, []{ function_name(__VA_ARGS__); }, nil )


#define FUN( pre, run, post, function_name )

    new RUNNER( #function_name, pre, run, post )


//=============================================================================

// kukyakya


#include <memory>

#include <cassert>


using byte = char;

using word = std::size_t;


word merge_word( const word& w1, const word& w2, std::size_t byte_offset )

{

    [...] ) );


    const std::size_t shift_1 = CHAR_BIT * byte_offset;

    const std::size_t shift_2 = CHAR_BIT * sizeof( word ) - shift_1;


#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

    return ( w1 >> shift_1 ) | ( w2 << shift_2 );

#else

    return ( w1 << shift_1 ) | ( w2 >> shift_2 );

#endif // __BYTE_ORDER

}


std::size_t get_byte_offset( const word* ptr )

{

    void *p = (void*)ptr;

    std::size_t sz = -1;


    std::align( alignof( word ), 0, p, sz );


    const auto diff = (char*)p - (char*)ptr;


    return ( diff == 0 ) ? 0 : ( sizeof( word ) - diff );

}


byte* copy_byte( byte* dest, const byte* src, std::size_t n_byte )

{

    // Don't fuck with loop-unrolling, just trust your compiler

    while( n_byte-- )

        *dest++ = *src++;


    return dest;

}


word* copy_word_both_aligned( word* dest, const word* src, std::size_t n_word )

{

    /* */ word* d = (word*)dest;

    const word* s = (const word*)src;

    while( n_word-- )

        *d++ = *s++;


    return dest;

}


// src is not aligned

word* copy_word_dest_aligned( word* dest, const word* src, std::size_t n_word )

{

    word *d = dest;

    const word *s = src;


    // get byte-offset of src

    std::size_t src_offset = get_byte_offset( s );


    // if src is aligned, call copy_word_both_aligned

    if( src_offset == 0 )

    {

        return copy_word_both_aligned( d, s, n_word );

    }


    const word* aligned_src = (const word*)( (char*)s - src_offset );

    [...] == 0 );


    word buf = *aligned_src++;

    while( n_word-- )

    {

        word buf2 = *aligned_src++;

        *d++ = merge_word( buf, buf2, src_offset );

        buf = buf2;

    }


    return dest;

}


void *kukyakya_memcpy( void* dest, const void* src, std::size_t n )

{

    /* */ void* d = dest;

    const void* s = src;

    std::size_t sz = n;


    if( !std::align( alignof( word ), 0, d, sz ) )

    {

        return copy_byte( (byte*)dest, (const byte*)src, n );

    }

    s = (const byte*)s + ( n - sz );


    // byte copy until dest is aligned

    copy_byte( (byte*)dest, (const byte*)src, n - sz );


    // copy words

    const std::size_t n_word = sz / sizeof( word );

    copy_word_dest_aligned( (word*)d, (const word*)s, n_word );

    d = /* */ (word*)d + n_word;

    s = (const word*)s + n_word;

    sz -= sizeof( word )   * n_word;


    // copy remaining bytes

    copy_byte( (byte*)d, (const byte*)s, sz );


    return dest;

}


void *kukyakya_memcpy_unaligned( void* dest, const void* src, std::size_t n_byte )

{

    /* */ word *d = (/* */ word*)dest;

    const word* s = (const word*)src;


    // copy word

    const std::size_t n_word = n_byte / sizeof( word );

    copy_word_both_aligned( d, s, n_word );


    d += n_word;

    s += n_word;

    n_byte -= n_word * sizeof( word );


    // copy remaining bytes

    copy_byte( (byte*)d, (const byte*)s, n_byte );


    return dest;

}


void *my_memcpy_byte_only( void* dest, const void* src, std::size_t n )

{

    return copy_byte( (byte*)dest, (const byte*)src, n );

}

//=============================================================================


void* codesafer_memcpy_unaligned1( void* dst, const void* src, std::size_t size )

{

    using   step_t    = u32;


    _____   step_t* d = (step_t*)dst;

    const   step_t* s = (step_t*)src;

    const   std::size_t step_count  = size / sizeof(step_t);

    const   u32         off_road    = size % sizeof(step_t);


    for( std::size_t i = 0; i < step_count; ++i )

        d[i] = s[i];


    u8* db = (u8*)( d + step_count );

    u8* sb = (u8*)( s + step_count );


    for( u32 i = 0; i < off_road; ++i )

        db[i] = sb[i];


    return  dst;

}

//=============================================================================

// test case


const int   test_count = 100;

const int   test_size  = 1000000;


#ifdef _MSC_VER

__declspec( align( 4 ) )   char src[ test_size + 4 ];

__declspec( align( 4 ) )   char dst[ test_size + 4 ];

#else

char src[ test_size + 4 ] __attribute__((aligned(4)));

char dst[ test_size + 4 ] __attribute__((aligned(4)));

#endif


int         result1, result2, result3, result4;


void init()

{

}


void pre()

{

}


void test1()

{

    result1 += (int)kukyakya_memcpy( dst + 1, src + 3, test_size );

}


void test2()

{

    result2 += (int)kukyakya_memcpy_unaligned( dst + 1, src + 3, test_size );

}


void test3()

{

    result3 += (int)memcpy( dst + 1, src + 3, test_size );

}


void test4()

{

    result4 += (int)codesafer_memcpy_unaligned1( dst + 1, src + 3, test_size );

}


bool post()

{

    return  true;

}

//-----------------------------------------------------------------------------


#include <iostream>


using   namespace   std;


int main()

{

    init();

    BENCH< test_count > bench;

    bench.add( FUN( pre, test1, post, kukyakya_aligned ) );

    bench.add( FUN( pre, test2, post, kukyakya_unaligned ) );

    bench.add( FUN( pre, test3, post, std_memcpy ) );

    bench.add( FUN( pre, test4, post, codesafer_unaligned1 ) );

    bench.run();


    return  0;

}


추천 비추천

25

고정닉 0

4

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 며느리, 사위되면 시댁, 처가에 잘할 것 같은 스타 운영자 25/10/13 - -
AD 프로게이머가 될테야!! 운영자 25/10/01 - -
공지 프로그래밍 갤러리 이용 안내 [96] 운영자 20.09.28 47931 65
2896488 후스넘버 허위 내리는법 (106.102) 00:56 8 0
2896485 캄보디아 이거 진짜 무섭네 [4] 노력갤로그로 이동합니다. 00:54 30 0
2896484 ( ㅇ ㅅ ㅇ )a [1] 노력갤로그로 이동합니다. 00:54 13 0
2896483 냥덩아 발명도둑잡기(118.216) 00:53 8 0
2896482 지듣노 발명도둑잡기(118.216) 00:44 7 0
2896480 나르시 에이다 빠는거 보니까 예전에 클로저 빠는 아재 있었는데 [1] 박민준갤로그로 이동합니다. 00:35 27 0
2896478 패턴 매칭(Rust) vs. 직접 접근(Ada): 공정한 비교 나르시갤로그로 이동합니다. 00:30 9 0
2896477 제미니의 편향: Ada는 상대적으로 복잡한 것처럼 서술했네 ㅎㅎ 나르시갤로그로 이동합니다. 00:29 9 0
2896475 현시대는 토발즈도 1찍 짱깨편인 무서운 시대이다ㅋㅋ번식 더 해줘라 이기 타이밍뒷.통수한방(1.213) 00:28 9 0
2896473 인터넷에서 싸우지 마라 [1] 박민준갤로그로 이동합니다. 00:26 32 0
2896472 "대통령님, '소비쿠폰' 저도 할 말 있습니다" 발명도둑잡기(118.216) 00:26 14 0
2896471 제미니의 러스트 편향성: Addr.Addr_V4'Image 이거 아니잖 나르시갤로그로 이동합니다. 00:25 12 0
2896469 와.. 일본은 브라질 이겻넹 ㄷㅅㄷ ♥덩냥이♥갤로그로 이동합니다. 00:23 13 0
2896468 이재명 "홍석천도 폐업..자영업자 임대료 감면에 정부 나서 달라" 발명도둑잡기(118.216) 00:21 8 0
2896467 Rust 의 Result 가 대체 왜 편하다는 것??? 나르시갤로그로 이동합니다. 00:14 11 0
2896465 제미니마저 Rust에 편향되게 설명하네. ㅎㅎ 나르시갤로그로 이동합니다. 00:12 16 0
2896464 요즘 컴공은 next.js도 가르침? [4] ㅇㅇ(211.196) 00:08 36 0
2896463 멍유야 이것만 알아둬 [2] ♥덩냥이♥갤로그로 이동합니다. 00:04 28 0
2896460 Ada와 Rust 비교: 자료구조, 분기, 오류 처리 철학 [1] 나르시갤로그로 이동합니다. 10.14 16 0
2896458 [공지] 멍퀴벌레 신상 제보 받습니다 현상금 있음 ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896456 최근 영화 <추적>을 발표한 최승호 감독이 발명도둑잡기(118.216) 10.14 9 0
2896455 124.48 점마 진짜 개발지식 일천하노 ㅋㅋㅋ [1] ㅆㅇㅆ(124.216) 10.14 37 0
2896446 멍퀴벌레는 21세기 홍길동이당 By 나님 [4] ♥덩냥이♥갤로그로 이동합니다. 10.14 28 0
2896445 Ada 프로그래밍: 열거형과 선택 구조, 그리고 예외 처리 나르시갤로그로 이동합니다. 10.14 16 0
2896442 Ada 프로그래밍: 3.5 주석 (Comment) 나르시갤로그로 이동합니다. 10.14 9 0
2896439 진중권이 말하는 극좌 [2] ♥덩냥이♥갤로그로 이동합니다. 10.14 20 0
2896435 이거 강의 언제 어디서 듣나요 발명도둑잡기(118.216) 10.14 14 0
2896434 냥덩이는 털바퀴가 된당⭐+ 7화 ♥덩냥이♥갤로그로 이동합니다. 10.14 17 0
2896432 안목 유튜브 보고 스포이더로 똑같이. 넥도리아(220.74) 10.14 15 0
2896431 [공지] 나님.. 이 모든 사태에 대해 책임지고 탈갤합니당.. [1] ♥덩냥이♥갤로그로 이동합니다. 10.14 28 0
2896428 냥덩 도배 발명도둑잡기(118.216) 10.14 18 0
2896427 냥덩아 적당히해 [6] 개멍청한유라갤로그로 이동합니다. 10.14 45 0
2896424 샤미 “K-팝은 더 성장할 것…韓 아티스트 영입 검토” [1] 발명도둑잡기(118.216) 10.14 18 0
2896420 현시대는 토발즈도 1찍 짱깨편인 무서운 시대이다ㅋㅋ번식 더 해줘라 이기 타이밍뒷.통수한방(1.213) 10.14 10 0
2896418 [공지]냥덩강점기 종료~ 나님 야구 보면서 잘 놀다갑니당~ ♥덩냥이♥갤로그로 이동합니다. 10.14 26 0
2896417 비선실세 국정농단 의혹 김현지 제보 받습니당⭐ ♥덩냥이♥갤로그로 이동합니다. 10.14 28 1
2896416 와 벌써 시간 이렇게 됐네 잘 준비해야지 [2] chironpractor갤로그로 이동합니다. 10.14 23 0
2896415 김광현 ㅋㅅㅋ ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896414 18년인가 양현종 마무리 우승이 ㄹㅇ 소름끼쳤는데 ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896413 애널 야구 좀 싱겁게 끝나서 아쉽 ♥덩냥이♥갤로그로 이동합니다. 10.14 13 0
2896412 김서현도 공이 빠른건 맞긴한데 제구 구리다던데 ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896411 폰세 막판에 퍼진거 같던데 ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896410 폰세 1차 나오면 삼성 1차전은 버리려나보네 [6] ♥덩냥이♥갤로그로 이동합니다. 10.14 31 0
2896409 타자들이 투수에 익숙해지면 불리 하니까 ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896408 김경문 감독이 우승하려고 폰세 약팀만 보냇다네 ♥덩냥이♥갤로그로 이동합니다. 10.14 13 0
2896407 폰세가 빠따 강한팀은 일부러 빼왓다는데? ♥덩냥이♥갤로그로 이동합니다. 10.14 13 0
2896406 삼성유튜브 보니까 개웃기넹 ㅋㅅㅋ ♥덩냥이♥갤로그로 이동합니다. 10.14 17 0
2896405 큰경기에 강하고 작은경기에 약한;; ♥덩냥이♥갤로그로 이동합니다. 10.14 14 0
2896404 근데 국내트로피는 없응 ♥덩냥이♥갤로그로 이동합니다. 10.14 13 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

디시미디어

디시이슈

1/2