add multi-thread version