Browse Source

Merge branch 'core_perf' of https://github.com/arkpar/cpp-ethereum into arkpar-core_perf

cl-refactor
Gav Wood 10 years ago
parent
commit
9e18fe20ec
  1. 4
      alethzero/DownloadView.cpp
  2. 16
      cmake/EthCompilerSettings.cmake
  3. 5
      libdevcore/FixedHash.h
  4. 13
      libdevcore/Guards.h
  5. 4
      libdevcore/Log.cpp
  6. 11
      libethcore/EthashAux.cpp
  7. 4
      libethereum/BlockChain.cpp
  8. 17
      libethereum/BlockChain.h
  9. 13
      libethereum/BlockDetails.h
  10. 2
      libethereum/DownloadMan.cpp
  11. 3
      libethereum/DownloadMan.h
  12. 2
      libethereum/EthereumHost.cpp
  13. 19
      libethereum/EthereumPeer.cpp

4
alethzero/DownloadView.cpp

@ -39,13 +39,13 @@ void DownloadView::paintEvent(QPaintEvent*)
QPainter p(this);
p.fillRect(rect(), Qt::white);
if (!m_man || m_man->chain().empty() || !m_man->subCount())
if (!m_man || m_man->chainEmpty() || !m_man->subCount())
return;
double ratio = (double)rect().width() / rect().height();
if (ratio < 1)
ratio = 1 / ratio;
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chain().size() / ratio)));
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chainSize() / ratio)));
// QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n));
QSizeF area(n, n);

16
cmake/EthCompilerSettings.cmake

@ -9,14 +9,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_RELEASE")
if (PROFILING)
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
add_definitions(-DETH_PROFILING_GPERF)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
endif ()
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
@ -61,6 +53,14 @@ else ()
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.")
endif ()
if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
add_definitions(-DETH_PROFILING_GPERF)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
endif ()
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
option(USE_LD_GOLD "Use GNU gold linker" ON)
if (USE_LD_GOLD)

5
libdevcore/FixedHash.h

@ -64,6 +64,9 @@ public:
/// Convert from the corresponding arithmetic type.
FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
/// Convert from unsigned
explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); }
/// Explicitly construct, copying from a byte array.
explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
@ -80,7 +83,7 @@ public:
operator Arith() const { return fromBigEndian<Arith>(m_data); }
/// @returns true iff this is the empty hash.
explicit operator bool() const { return ((Arith)*this) != 0; }
explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); }
// The obvious comparison operators.
bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }

13
libdevcore/Guards.h

@ -22,6 +22,7 @@
#pragma once
#include <mutex>
#include <atomic>
#include <boost/thread.hpp>
namespace dev
@ -61,6 +62,18 @@ struct GenericUnguardSharedBool
MutexType& m;
};
/** @brief Simple lock that waits for release without making context switch */
class SpinLock
{
public:
SpinLock() { m_lock.clear(); }
void lock() { while (m_lock.test_and_set(std::memory_order_acquire)) {} }
void unlock() { m_lock.clear(std::memory_order_release); }
private:
std::atomic_flag m_lock;
};
using SpinGuard = std::lock_guard<SpinLock>;
/** @brief Simple block guard.
* The expression/block following is guarded though the given mutex.
* Usage:

4
libdevcore/Log.cpp

@ -158,8 +158,8 @@ void dev::setThreadName(string const& _n)
void dev::simpleDebugOut(std::string const& _s, char const*)
{
static Mutex s_lock;
Guard l(s_lock);
static SpinLock s_lock;
SpinGuard l(s_lock);
cerr << _s << endl << flush;

11
libethcore/EthashAux.cpp

@ -87,13 +87,10 @@ ethash_params EthashAux::params(h256 const& _seedHash)
{
Guard l(get()->x_epochs);
unsigned epoch = 0;
try
auto epochIter = get()->m_epochs.find(_seedHash);
if (epochIter == get()->m_epochs.end())
{
epoch = get()->m_epochs.at(_seedHash);
}
catch (...)
{
// cdebug << "Searching for seedHash " << _seedHash;
// cdebug << "Searching for seedHash " << _seedHash;
for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {}
if (epoch == 2048)
{
@ -102,6 +99,8 @@ ethash_params EthashAux::params(h256 const& _seedHash)
throw std::invalid_argument(error.str());
}
}
else
epoch = epochIter->second;
return params(epoch * ETHASH_EPOCH_LENGTH);
}

4
libethereum/BlockChain.cpp

@ -767,7 +767,7 @@ void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const
m_inUse.insert(id);
}
template <class T> static unsigned getHashSize(map<h256, T> const& _map)
template <class T> static unsigned getHashSize(unordered_map<h256, T> const& _map)
{
unsigned ret = 0;
for (auto const& i: _map)
@ -855,7 +855,7 @@ void BlockChain::garbageCollect(bool _force)
}
}
m_cacheUsage.pop_back();
m_cacheUsage.push_front(std::set<CacheID>{});
m_cacheUsage.push_front(std::unordered_set<CacheID>{});
}
void BlockChain::checkConsistency()

17
libethereum/BlockChain.h

@ -28,6 +28,8 @@
#include <deque>
#include <chrono>
#include <unordered_map>
#include <unordered_set>
#include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include <libdevcore/Guards.h>
@ -40,6 +42,11 @@
#include "BlockQueue.h"
namespace ldb = leveldb;
template <> struct std::hash<std::pair<dev::h256, unsigned>>
{
size_t operator()(const pair<dev::h256, unsigned> &x ) const { return std::hash<dev::h256>()(x.first) ^ std::hash<unsigned>()(x.second); }
};
namespace dev
{
@ -66,7 +73,7 @@ std::map<Address, Account> const& genesisState();
ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0);
using BlocksHash = std::map<h256, bytes>;
using BlocksHash = std::unordered_map<h256, bytes>;
using TransactionHashes = h256s;
using UncleHashes = h256s;
using ImportRoute = std::pair<h256s, h256s>;
@ -144,7 +151,7 @@ public:
UncleHashes uncleHashes() const { return uncleHashes(currentHash()); }
/// Get the hash for a given block's number.
h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras<BlockHash, ExtraBlockHash>(h256(u256(_i)), m_blockHashes, x_blockHashes, NullBlockHash).value; }
h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras<BlockHash, ExtraBlockHash>(h256(_i), m_blockHashes, x_blockHashes, NullBlockHash).value; }
/// Get the last N hashes for a given block. (N is determined by the LastHashes type.)
LastHashes lastHashes() const { return lastHashes(number()); }
@ -251,7 +258,7 @@ private:
void open(std::string const& _path, WithExisting _we = WithExisting::Trust);
void close();
template<class T, unsigned N> T queryExtras(h256 const& _h, std::map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
template<class T, unsigned N> T queryExtras(h256 const& _h, std::unordered_map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
{
{
ReadGuard l(_x);
@ -295,8 +302,8 @@ private:
using CacheID = std::pair<h256, unsigned>;
mutable Mutex x_cacheUsage;
mutable std::deque<std::set<CacheID>> m_cacheUsage;
mutable std::set<CacheID> m_inUse;
mutable std::deque<std::unordered_set<CacheID>> m_cacheUsage;
mutable std::unordered_set<CacheID> m_inUse;
void noteUsed(h256 const& _h, unsigned _extra = (unsigned)-1) const;
std::chrono::system_clock::time_point m_lastCollection;

13
libethereum/BlockDetails.h

@ -21,6 +21,7 @@
#pragma once
#include <unordered_map>
#pragma warning(push)
#pragma warning(disable: 4100 4267)
#include <leveldb/db.h>
@ -114,12 +115,12 @@ struct TransactionAddress
static const unsigned size = 67;
};
using BlockDetailsHash = std::map<h256, BlockDetails>;
using BlockLogBloomsHash = std::map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::map<h256, BlockReceipts>;
using TransactionAddressHash = std::map<h256, TransactionAddress>;
using BlockHashHash = std::map<h256, BlockHash>;
using BlocksBloomsHash = std::map<h256, BlocksBlooms>;
using BlockDetailsHash = std::unordered_map<h256, BlockDetails>;
using BlockLogBloomsHash = std::unordered_map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::unordered_map<h256, BlockReceipts>;
using TransactionAddressHash = std::unordered_map<h256, TransactionAddress>;
using BlockHashHash = std::unordered_map<h256, BlockHash>;
using BlocksBloomsHash = std::unordered_map<h256, BlocksBlooms>;
static const BlockDetails NullBlockDetails;
static const BlockLogBlooms NullBlockLogBlooms;

2
libethereum/DownloadMan.cpp

@ -50,7 +50,7 @@ h256Set DownloadSub::nextFetch(unsigned _n)
m_indices.clear();
m_remaining.clear();
if (!m_man || m_man->chain().empty())
if (!m_man || m_man->chainEmpty())
return h256Set();
m_asked = (~(m_man->taken() + m_attempted)).lowest(_n);

3
libethereum/DownloadMan.h

@ -143,7 +143,8 @@ public:
return ret;
}
h256s chain() const { ReadGuard l(m_lock); return m_chain; }
size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); }
size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); }
void foreachSub(std::function<void(DownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); }
unsigned subCount() const { ReadGuard l(x_subs); return m_subs.size(); }
RangeMask<unsigned> blocksGot() const { ReadGuard l(m_lock); return m_blocksGot; }

2
libethereum/EthereumHost.cpp

@ -122,7 +122,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who, bool _clemency)
// Done our chain-get.
clog(NetNote) << "Chain download complete.";
// 1/100th for each useful block hash.
_who->addRating(m_man.chain().size() / 100);
_who->addRating(m_man.chainSize() / 100);
m_man.reset();
}
else if (_who->isSyncing())

19
libethereum/EthereumPeer.cpp

@ -329,9 +329,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
case GetTransactionsPacket: break; // DEPRECATED.
case TransactionsPacket:
{
clog(NetAllDetail) << "Transactions (" << dec << _r.itemCount() << "entries)";
unsigned itemCount = _r.itemCount();
clog(NetAllDetail) << "Transactions (" << dec << itemCount << "entries)";
Guard l(x_knownTransactions);
for (unsigned i = 0; i < _r.itemCount(); ++i)
for (unsigned i = 0; i < itemCount; ++i)
{
auto h = sha3(_r[i].data());
m_knownTransactions.insert(h);
@ -373,21 +374,22 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
}
case BlockHashesPacket:
{
clog(NetMessageSummary) << "BlockHashes (" << dec << _r.itemCount() << "entries)" << (_r.itemCount() ? "" : ": NoMoreHashes");
unsigned itemCount = _r.itemCount();
clog(NetMessageSummary) << "BlockHashes (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreHashes");
if (m_asking != Asking::Hashes)
{
cwarn << "Peer giving us hashes when we didn't ask for them.";
break;
}
if (_r.itemCount() == 0)
if (itemCount == 0)
{
transition(Asking::Blocks);
return true;
}
unsigned knowns = 0;
unsigned unknowns = 0;
for (unsigned i = 0; i < _r.itemCount(); ++i)
for (unsigned i = 0; i < itemCount; ++i)
{
addRating(1);
auto h = _r[i].toHash<h256>();
@ -454,12 +456,13 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
}
case BlocksPacket:
{
clog(NetMessageSummary) << "Blocks (" << dec << _r.itemCount() << "entries)" << (_r.itemCount() ? "" : ": NoMoreBlocks");
unsigned itemCount = _r.itemCount();
clog(NetMessageSummary) << "Blocks (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBlocks");
if (m_asking != Asking::Blocks)
clog(NetWarn) << "Unexpected Blocks received!";
if (_r.itemCount() == 0)
if (itemCount == 0)
{
// Got to this peer's latest block - just give up.
transition(Asking::Nothing);
@ -472,7 +475,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
unsigned got = 0;
unsigned repeated = 0;
for (unsigned i = 0; i < _r.itemCount(); ++i)
for (unsigned i = 0; i < itemCount; ++i)
{
auto h = BlockInfo::headerHash(_r[i].data());
if (m_sub.noteBlock(h))

Loading…
Cancel
Save