prettify

Aug 15, 2017

Downsize PDF file to lower resolution on MacOS

I exported a image to a PDF in the file->print menu of the photo app of MacOS. The problem is, the image was saved as original resolution thus the PDF file is way too huge. I need to lower the resolution to something like 150DPI. I serach for a while and found those 2 solutions which I love best 1. Use GhostScript https://blog.omgmog.net/post/compressing-pdf-from-your-mac-or-linux-terminal-with-ghostscript/ 2. Quartz Filters. If you do not like command line, download the filter files from https://github.com/joshcarr/Apple-Quartz-Filters Then sudo mkdir /Library/Filters sudo mv *.qfilter /Library/Filters the open PDF file in preview, File->Export, you'll be able to choose a quartz filter

Oct 17, 2016

C++11: lambda, bind, thread

#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
int main()
{
    // vector container stores threads
    std::vector<std::thread> workers;
    for (int i = 0; i < 5; i++) {
        workers.push_back(std::thread([i]() 
        {
            std::cout << i << std::endl;
        }));
    }

    std::for_each(workers.begin(), workers.end(), [](std::thread &t) 
    {
        t.join();
    });
    std::cout << "end\n";

    return 0;
}
11:21am - hi ran 35 lines of C++ (finished in 1.29s):
14 
0 
2 
 
3 
end 

C++ 11: array, auto, range based loop, enum

1. std::array is a static vector. The size of std::array can not be changed after it was compiled, thus is it often more efficient than std::vector.

std:array<int> nums={1,3,4,9};
for(auto i=nums.begin(); i!=nums.end(); ++i) cout << i << " ";

2. auto type and range based loop
std:array<int> nums={1,3,4,9};
for(auto& i: nums) cout << i << " ";

then range based loop almost can apply to any complicated type, e.g

map<int,string> m;
for(auto& x: m) cout<<x.first << ":" << x.second << endl;

pair<int,int> p;
for(auto& x: p) cout <<x.first <<":"<<x.second<<endl;

vector<int> a;
for(auto& x: a) cout << x << endl;

priority_queue<int> pq;
for(auto& x: pq) cout <<x<<endl;

3. enum class
enum class color {red, green, blue};
color c=color::green;


C++ 11: override

The C++ 11 have a new keyword: "override". Let me use an example to explain how it works.

#include 

class base
{
  public:
    virtual void f1()
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    };
    virtual void f2() final
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    virtual void f3()
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    void f4()
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    virtual void f5()
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

class child final: public base
{
  public:
    virtual void f1() override//(1)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    /*virtual void f2()override//(2)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }*/
    /*virtual void f2()(3)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }*/
    /*void f2()(4)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }*/
    virtual void f3()//(5)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    /*virtual void f4()override//(6)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }*/
    virtual void f4()//(7)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
    void f5() override//(8)
    {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

int main()
{
  std::cout << "base" << std::endl;
  base a;
  a.f1();
  a.f2();
  a.f3();
  a.f4();
  a.f5();

  std::cout << "child" << std::endl;
  child b;
  b.f1();
  b.f2();
  b.f3();
  b.f4();
  b.f5();

  std::cout << "base*" << std::endl;
  base* p = new child();
  p->f1();
  p->f2();
  p->f3();
  p->f4();
  p->f5();
}

Run and I got the following results
4:50pm - ran 90 lines of C++ (finished in 766ms):
base 
virtual void base::f1() 
virtual void base::f2() 
virtual void base::f3() 
void base::f4() 
virtual void base::f5() 
child 
virtual void child::f1() 
virtual void base::f2() 
virtual void child::f3() 
virtual void child::f4() 
virtual void child::f5() 
base* 
virtual void child::f1() 
virtual void base::f2() 
virtual void child::f3() 
void base::f4() 
virtual void child::f5() 


Here are the comments( refer to the child class code)
(1) explicitly override a base class virtual function, that's ok
(2) explicitly override a base class final virtual function, that's not allowed by compiler
(3) implicitly override a base class final virtual function, that's not allowed by compiler
(4) not allowed by compiler since the base f2() is final
(5) implicitly  override a base class virtual function, compiler won't point out the issue if the base virtual function does not exist
(6) override can not works with virtual function, compiling error
(7) declare f4() as virtual, this is modify, not overide
(8) no virtual required here

Oct 4, 2016

Some NVMe links

NVMe Compliance Test
https://github.com/nvmecompliance/tnvme

Linux driver for NVMe Compliance Suite
https://github.com/nvmecompliance/dnvme

Linux NVME command interface
https://github.com/linux-nvme/nvme-cli

NVM-Express user utilities and test programs
http://git.infradead.org/users/kbusch/nvme-user.git

NVME Windows driver (OFA)
http://www.nvmexpress.org/windows-driver-microsoft-inbox/

NVME windows command issuer
https://github.com/Miyavi-Chen/NVMe_CMD_issuer

Sep 18, 2016

Nand flash quick notes

chip->plane->block->page/oob(out of band redundancy area) page is typically 2k 4k 8k. block is typically 128k 256k 512k bit flip, ecc Nand flash interface I/o pins: I/O0-7, CLE(command latch enable), ALE(address latch enable), CE (chip enable), RE(read enable), WE(write enable) page register on nand flash is a page buffer, user has to issue command 0x10 to write into nand BBT(bad block table), bad block management ONFI(open nand flash interface) standard copy back is a feature which support directly copy one page to another (don't have to go external bus) page read 0x30, 0x00 page write 0x80, 0x10 read id 0x90 block erase 0x60, 0xd0

Aug 15, 2016

Cross compile lm benchmark for ARM

$ wget http://www.bitmover.com/lmbench/lmbench3.tar.gz
$ tar -zxvf lmbench3.tar.gz
$ cd lmbench3/src
$ cp Makefile Makefile.bak
$ vim Makefile
$ diff Makefile.bak Makefile
114c114
<  @env CFLAGS=-O MAKE="$(MAKE)" MAKEFLAGS="$(MAKEFLAGS)" CC="$(CC)" OS="$(OS)" ../scripts/build all
---
>  @env CFLAGS="-O -static" MAKE="$(MAKE)" MAKEFLAGS="$(MAKEFLAGS)" CC="$(CC)" OS="$(OS)" ../scripts/build all
231c231
< $O/lmbench : ../scripts/lmbench bk.ver
---
> $O/lmbench : ../scripts/lmbench #bk.ver
$ make CC=/opt/aarch64/aarch64v8-marvell-linux-gnu-5.2.1_i686_20151110/bin/aarch64-linux-gnu-gcc OS=arm-linux TARGET=linux 

An example script to run memory test only


#!/bin/bash -x

exec 2>&1

target=linux
sizes="1k 4k 16k 32k 128k 256k 512k 1m 2m 4m 8m" 
stride="32 128 1024"

date

LOGFILE="benchmark_run_raw.log"
LOGFILE2="benchmark_run.log"
echo "Creating / cleaning out file.";
cat /dev/null > $LOGFILE;
cat /dev/null > $LOGFILE2;

TITLE=`basename ${PWD}`
echo ">>>>>>   Benchmarks is $TITLE" >> $LOGFILE

echo "\"------mhz \"">> $LOGFILE
${RUNPREFIX} ./mhz  >> $LOGFILE

echo "\"------stream -v 1 -M 8k -W5 -N 10\"">>  $LOGFILE
${RUNPREFIX} ./stream -v 1 -M 8k -W5 -N 10 2>> $LOGFILE
echo "\"------stream -v 1 -M 128k -W5 -N 10\"">>  $LOGFILE
${RUNPREFIX} ./stream -v 1 -M 128k -W5 -N 10 2>> $LOGFILE
echo "\"------stream -v 1 -M 3m -W5 -N 10\"">>  $LOGFILE
${RUNPREFIX} ./stream -v 1 -M 3m -W5 -N 10 2>> $LOGFILE


for ds in ${stride}; do
 echo "\"------lat_mem_rd \"">>  $LOGFILE
    ${RUNPREFIX} ./lat_mem_rd $(echo ${sizes} | awk '{print $NF}') ${ds}  2>> $LOGFILE
done

echo "\"------bw_mem frd \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} frd  2>> $LOGFILE
done

echo "\"------bw_mem rd \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} rd  2>> $LOGFILE
done

    echo "\"------bw_mem wr \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} wr  2>> $LOGFILE
done

echo "\"------bw_mem fwr \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} fwr  2>> $LOGFILE
done

echo "\"------bw_mem fcp \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} fcp  2>> $LOGFILE
done

echo "\"------bw_mem cp \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} cp  2>> $LOGFILE
done

echo "\"------bw_mem rdrw \"">>  $LOGFILE
for ds in ${sizes}; do
    ${RUNPREFIX} ./bw_mem ${ds} rdwr  2>> $LOGFILE
done

echo "<<<<<<   End of $TITLE" >> $LOGFILE

cat $LOGFILE | sed -r -e '/stream -v 1 -M 8k/,/------lat_mem_rd/s/(.*): (.*) (.*)/\1(\3),\2/' -e '/stride=32/,/------bw_mem frd/s/^0.00977.*|^0.01367.*|^0.01758.*|^0.01953.*|^0.02148.*|^0.02539.*|^0.02734.*|^0.0293.*|^0.03516.*|^0.03906.*|^0.04297.*|^0.05078.*|^0.05469.*|^0.05859.*|^0.07031.*|^0.07812.*|^0.08594.*|^0.10156.*|^0.10938.*|^0.11719.*|^0.14062.*|^0.15625.*|^0.17188.*|^0.20312.*|^0.21875.*|^0.23438.*|^0.28125.*|^0.3125.*|^0.34375.*|^0.40625.*|^0.4375.*|^0.46875.*|^0.5625.*|^0.625.*|^0.6875.*|^0.8125.*|^0.875.*|^0.9375.*|^1.125.*|^1.25.*|^1.375.*|^1.625.*|^1.75.*|^1.875.*|^2.25.*|^2.5.*|^2.75.*|^3.25.*|^3.5.*|^3.75.*|^4.5.*|^5.*|^5.5.*|^6.5.*|^7.0.*|^7.5.*//' -e '/stride=1024/,/------bw_mem frd/s/^0.00049.*|^0.00098.*|^0.00195.*|^0.00293.*|^0.00391.*|^0.00586.*|^0.00781.*|^0.01172.*|^0.01562.*|^0.02344.*|^0.03125.*|^0.04688.*|^0.0625.*|^0.09375.*|^0.125.*|^0.1875.*|^0.25.*|^0.375.*|^0.5.*|^6.0000.*|^0.75.*|^3.0.*//' -e '/^$/d' -e 's/"stride/stride/' -e 's/([0-9]) ([0-9])/\1,\2/' > $LOGFILE2

date

here is a link that describe how to use lmbenchmark in detail: http://www.hexiongjun.com/?p=174