compiling ace (linux)

compiling ace (linux)

  • fast download (2020-04-05)

e.g.

# ACE-x.y.z.tar.bz2
axel -an 32 http://download.dre.vanderbilt.edu/previous_versions/ACE-6.2.1.tar.bz2

# or
axel -an 32 http://download.dre.vanderbilt.edu/previous_versions/ACE-6.4.0.tar.bz2
  • unpack and prepare
# unpack
cd /path/to/wrapper/repo/root
git checkout v6.2.1

# or:
tar -xf ACE-6.2.1.tar.bz2
cd ACE_wrappers/

# prepare
# set the environment variable ACE_ROOT to point to the directory where ace is
# unpacked, update your .bashrc accordingly e.g.:
export ACE_ROOT=$(pwd)

# Build a symlink to config.h as (config.h is in ACE_wrappers/ace):
cd $ACE_ROOT/ace

# and (which can be found in ACE_wrappers/include/makeinclude):
cd $ACE_ROOT/include/makeinclude
ln -s platform_linux.GNU platform_macros.GNU
  • compile
cd $ACE_ROOT/ace
make clean
make -j
  • install
cd $ACE_ROOT
sudo -s bash
export ACE_ROOT=$(pwd)

# If you wish to install ACE (using "make install"), set the installation
# prefix in platform_macros.GNU.
cd $ACE_ROOT/include/makeinclude

# INSTALL_PREFIX = /opt/lib/ace-6.2.1

cd $ACE_ROOT/ace
make install

# cleanup
make clean

sudo rm -rf *

exit

git checkout -- .
  • pack
cd /opt/lib/ace6.2.1

tar -cjf ../ace6.2.1-xenial-amd64.tar.bz2 .

refs

install pre-built debian package (16.04)

curl -s https://yuiwong.org/debrepo/setup/setup-ubuntu-deb.sh | sudo bash

sudo apt update
sudo apt install libace6.2.1-nonofficial-dev

Find missing number (in C++)

Find missing number

Like the missing number problem, but given a list of N integers and these integers are in the range of [X, Y].
There are no duplicates in list. Maybe one or more than one of the integers is missing in the list.
Write an efficient code to find the first missing integer

— use binary search method:

/**
 * find the missing number (the first one) in a sorted array (min to max).
 * @tparam T integral value type,
 * @param nums the sorted numbers to find missing number.
 * @param nNums number count of @a nums.
 * @param rangeMin to find the number is this range.
 * @param rangeMax to find the number is this range.
 * @param[out] result result when success.
 * @return true when success, false when params invalid.
 *
 * @note
 * - @a nums should NOT nil, valid and sorted.
 * - @a nNums should valid.
 * - rangeMin should less than rangeMax!
 */
template<typename T>
typename CPPBASE2_ENABLE_IF<CPPBASE2_IS_INTEGRAL<T>::value, bool>::type
searchFirstMissingNumber(
  const T* const nums,
  const size_t nNums,
  const T rangeMin,
  const T rangeMax,
  T& result) {
  if ((!nums) || (rangeMin >= rangeMax)) {
    return false;
  }
  const T n = (rangeMax - rangeMin) + 1;
  if (uint64_t(n) <= nNums) {
    return false;
  }
  if (nNums < 1) {
    result = rangeMin;
    return true;
  }

  size_t leftIdx = 0;
  size_t rightIdx = nNums - 1;
  T expectMin = rangeMin;
  //T expectMax = rangeMax;
  size_t midIdx;
  T expectMid;

  // e.g.1: [0, 9], {0, 1, 2, 3, 5, 6, 7, 8, 9}
  //     2: [0, 9], {0, 1, 2, 4, 5, 6, 7, 8, 9}
  //     3: [0, 9], {0, 1, 2, 3, 4, 6, 7, 8, 9}
  //     4: [0, 9], {7, 8}
  //     5: [0, 9], {9}
  //     6: [0, 9], {0}
  //     7: [0, 9], {0, 1, 2, 3, 4, 5, 7, 8, 9}
  //     8: [-3, 5], {-3, -2, -1, 2, 3, 4, 5}
  while (leftIdx <= rightIdx) {
    if (nums[leftIdx] > expectMin) {
      result = expectMin;
      return true;
    } else {
      midIdx = (leftIdx + rightIdx) / 2;
      expectMid = rangeMin + midIdx;
      const T& midNum = nums[midIdx];
      if ((midNum == expectMid)
        && ((midIdx >= rightIdx) || ((expectMid + 1) != nums[midIdx + 1]))) {
        result = expectMid + 1;
        return true;
      } else if (midNum > expectMid) {
        // search left
        rightIdx = midIdx - 1;
        //expectMax = midNum - 1;
        continue;
      }
      // search right
      leftIdx = midIdx + 1;
      expectMin = midNum + 1;
    }
  }

  throw std::logic_error("bug!");
  return false;
}

some test code:

TEST(m, large) {
  const int N = 1024 * 1024 * 100;
  std::vector<int> a;
  a.reserve(N);
  SteadyTime t1, t2;

  const Duration maxET = Duration::milliseconds(1);
  Duration sum1, sum2;

  for (int k = 0; k < 100; ++k) {
    int missingNumber = kRg->get32() % a.capacity();
    int missingNumber2 = kRg->get32() % a.capacity();
    if (missingNumber > missingNumber2) {
      std::swap(missingNumber, missingNumber2);
    }
    int offset = kRg->get32() % a.capacity();
    if (k % 2) {
      offset *= -1;
    }
    a.clear();
    for (int i = 0; i < N; ++i) {
      if (i != missingNumber && i != missingNumber2) {
        a.push_back(offset + i);
      }
    }
    int result = -1;
    t1 = SteadyTime::now();
    EXPECT_TRUE(algorithm::searchFirstMissingNumberSlow(
      a.data(), a.size(), offset, offset + (N - 1), result));
    t2 = SteadyTime::now();
    sum1 += (t2 - t1);

    EXPECT_EQ(offset + missingNumber, result);
    EXPECT_LE((t2 - t1), Duration::milliseconds(100));

    CPPBASE2_INFO("searchFirstMissingNumberSlow"
           " size " << a.size()
      << ", elapsed time " << (t2 - t1).toNanosec() << " ns, "
      << ", result = " << (offset + missingNumber));

    result = -1;
    t1 = SteadyTime::now();
    EXPECT_TRUE(algorithm::searchFirstMissingNumber(
      a.data(), a.size(), offset, offset + (N - 1), result));
    t2 = SteadyTime::now();
    sum2 += (t2 - t1);

    EXPECT_EQ(offset + missingNumber, result);
    EXPECT_LE((t2 - t1), maxET);

    CPPBASE2_INFO("searchFirstMissingNumber"
           " size " << a.size()
      << ", elapsed time " << (t2 - t1).toNanosec() << " ns, "
      << ", result = " << (offset + missingNumber));
  }

  EXPECT_LE((sum1.toNanosec() / 100), Duration::milliseconds(20).toNanosec());
  EXPECT_GE((sum1.toNanosec() / 100), Duration::milliseconds(5).toNanosec());
  EXPECT_LE((sum2.toNanosec() / 100), Duration::microseconds(10).toNanosec());
}

C++ 最佳实践之 M&M rule

C++ 最佳实践之 M&M rule

M&M rule: mutable and metux(or shared_mutex(rwlock) or atomic …) go together!!

首先典型的问题的由来:在设计一个类的时候,我们希望一些方法是 const 的,
然后呢,有些场景,我们又希望所有方法是线程安全,于是使用 shared_mutex 等,
但是 const 方法怎么办 ?不考虑一些 hack的方式,例如 const_cast、直接获取地址等,
— 于是就会使用 mutable 修饰 shared_mutex,这样 const 方法可以正常使用 shared_mutx
的对象的。

另外,

  • 在使用 lambda 表达式(closure)的时候,也可以使用 mutable 修饰,这样通过拷贝方式捕获的变量,也可以在 closure 中修改,但是只是修改了 closure 中的,外面的不受影响!当然如果不用修改,最好是 immutable 的!
  • 然后 C++98 也是可以使用 mutable,例如 gcc、vc 等都是支持的。

Guideline: Remember the “M&M rule”: For a member variable, mutable and mutex (or atomic) go together.

(1) For a member variable, mutable implies mutex (or equivalent): A mutable member variable is presumed to be a mutable shared variable and so must be synchronized internally—protected with a mutex, made atomic, or similar.

(2) For a member variable, mutex (or similar synchronization type) implies mutable: A member variable that is itself of a synchronization type, such as a mutex or a condition variable, naturally wants to be mutable, because you will want to use it in a non-const way (e.g., take a std::lock_guard) inside concurrent const member functions.


See also