예전 모 회사 프로그래머가 신의 한수를 알려주겠다고 memcpy를 한번 짜보라고 하시더군요..
그래서 그냥 생각나는데요 조금 노멀하게...
void MyMemcpy(void *dest, void *src, size_t len){
char *dest8 = (char*)&dest;
char *src8 = (char*)&src;
while(--len){
*dest8++ = *src8++;
}
}
ㅡ_ㅡ...
dest메모리 영역과 src메모리 영역이 겹치는지 확인하는 코드를 넣었습니다.
뭐 여기까지 하면 그래도 안전하지 않냐라는 생각이 들었습니다만...
최근 boost 라이브러리(mpl 프로그래밍)쪽을 공부하면서 이런 방법이 나오더군요..
#include <typeinfo>
#include <algorithm>
#include <iterator>
#include <memory>
#include <boost/test/included/prg_exec_monitor.hpp>
#include <boost/timer.hpp>
#include <boost/type_traits.hpp>
//기존의 copy와 차별화를 위한 네임스페이스
namespace opt{
namespace detail{
//이건 직접 대입시켜서 복사하는 방식
template<typename l1, typename l2, bool b>
l2 copy_imp(l1 first, l1 last, l2 out, const boost::integral_constant<bool, b>&)
{
while(first != last){
*out = *first;
++out;
++first;
}
return out;
}
//memcpy를 이용하는 방식
template<typename T>
T* copy_imp(const T *first, const T *last, const boost::true_type&)
{
memcpy(out, first, (last-first)*sizeof(T));
return out+(last-first);
}
}
//실제 copy명령어
template <typename l1, typename l2>
inline l2 copy(l1 first, l1 last, l2 out)
{
//복사하는것의 타입을 알아내서
typedef typename std::iterator_traits<l1>::value_type value_type;
//l1에대해서 "C& C::operator=(const C&);" 와 같은 정의가 없다면
//trivial_assignment operator 를 가지게 됨.
//하지만 컴파일러 능력상 이걸 알아내는건 제각각임;;;
return detail::copy_imp(first, last, out, boost::has_trivial_assign<value_type>());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
// 이 밑은 위의 소스를 테스트 하는 소스
const int array_size = 1000;
int i_array_[array_size] = {0,};
const int ci_array_[array_size] = {0,};
char c_array_[array_size] = {0,};
const char cc_array_[array_size] = {0,};
int *i_array = i_array_;
const int *ci_array = ci_array_;
char *c_array = c_array_;
const char *cc_array = cc_array_;
const int iter_count = 1000000;
using namespace std;
int cpp_main(int argc, char* argv[])
{
boost::timer t;
double result;
cout << "Measuring times in micro-seconds per "<< array_size << " elements processed" << endl;
cout << "Testing copy... " << endl;
cout << " [some standard liberay version may already perform this optimisation.]" << endl;
//////////////////////////////////////////////////////////////////////////
//cache load
opt::copy(ci_array, ci_array + array_size, i_array);
//time optimised verstion
t.restart();
for(int i=0; i< iter_count; ++i){
opt::copy(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "opt::copy<const int*, int*> : " << result << endl;
//////////////////////////////////////////////////////////////////////////
//cache load;
std::copy(ci_array, ci_array + array_size, i_array);
//time standard version
t.restart();
for(int i=0; i< iter_count; ++i){
std::copy(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "std::copy<const int*, int*> : " << result << endl;
//////////////////////////////////////////////////////////////////////////
//cache load
opt::copy(cc_array, cc_array + array_size, c_array);
//time optimised verstion
t.restart();
for(int i=0; i< iter_count; ++i){
opt::copy(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "opt::copy<const char*, char*> : " << result << endl;
//////////////////////////////////////////////////////////////////////////
//cache load;
std::copy(cc_array, cc_array + array_size, c_array);
//time standard version
t.restart();
for(int i=0; i< iter_count; ++i){
std::copy(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "std::copy<const char*, char*> : " << result << endl;
return 0;
}
메타프로그래밍은 프로그램 소스를 프로그래밍 하는 개념인데...
더 빠른 프로그램 속도를 갖게 하는 비법? 꼼수? 학문? 인거 같습니다.
진정한 신의 한수... orz....
문제는 내가 아직 이걸 프로젝트에 써먹으면서 머리로 이해 + 손으로 익어야 하는데.......
그나마 boost로 익히는 메타프로그래밍 이라는 책을 사서 봤지만....
미국 책 스타일... orz...
그냥 개념만 쫙 ~~~ 설명됬고... 제가 멍청해서 그런지 개념 잡기가 너무 난해 하네요..
영어로 표현하면 보는 내내 so what? 이라는 느낌밖에 안왔습니다. ㅠㅠ
어쨋든.. 요즘 boost 쪽... 꽤 유용하고 재미있는 프로그래밍 방법론이라 생각하네요..