Achtung: Chrome entleert euren Laptop-Akku schneller als nötig
-
dot schrieb:
Inwiefern das für das Anzeigen statischer HTML Seiten relevant ist, ist mir allerdings unklar.
Webseiten sind seit wohl 15 Jahren nicht mehr statisch. Dazu kommt, wie hustbaer sagt, dass es auch Plugins gibt, die das brauchen können. Und die laufen in einem Container innerhalb von Chrome, haben also wohl kaum Zugriff auf Systemfunktionen
-
Wobei es durchaus
OKwünschenswert wäre wenn sie ne Option machen. Ich würde allerdings empfehlen Default auf "timeBeginPeriod(1)" zu machen.
-
So, Ergebnisse meines eigenen kleinen Tests...
Weniger Optimization-gefährdet, weniger Memory-Bound, mehr Sinn (hoffentlich).Thread count: 4 RNG engine: ranlux64_3 Block size: 10000 Keys: 1 ... 9 : request timer resolution of 1 ... 9 milliseconds 0 : clear timer resolution request x : exit Mega-iterations/sec 28.23039 Mega-iterations/sec 27.81525 Mega-iterations/sec 28.12061 Mega-iterations/sec 28.21894 Mega-iterations/sec 28.23874 Mega-iterations/sec 28.23861 Mega-iterations/sec 28.21896 Mega-iterations/sec 28.12054 Mega-iterations/sec 28.14999 Mega-iterations/sec 28.22888 Mega-iterations/sec 28.22883 Mega-iterations/sec 28.23867 Mega-iterations/sec 28.18938 Mega-iterations/sec 28.21900 Mega-iterations/sec 28.22880 Mega-iterations/sec 28.21902 Requested timer resolution: 1 Mega-iterations/sec 28.19611 Mega-iterations/sec 28.06250 Mega-iterations/sec 28.07248 Mega-iterations/sec 28.16241 Mega-iterations/sec 28.18237 Mega-iterations/sec 28.17235 Mega-iterations/sec 28.15240 Mega-iterations/sec 28.16239 Mega-iterations/sec 28.18238 Mega-iterations/sec 28.15237 Mega-iterations/sec 28.16240 Mega-iterations/sec 28.12237 Mega-iterations/sec 28.05256 Mega-iterations/sec 28.02250 Mega-iterations/sec 28.19240 Mega-iterations/sec 28.15239 Mega-iterations/sec 28.17239 Mega-iterations/sec 27.99253 Mega-iterations/sec 28.15241 Mega-iterations/sec 28.15240 Removed timer resolution request. Mega-iterations/sec 28.20551 Mega-iterations/sec 28.22876 Mega-iterations/sec 28.11067 Mega-iterations/sec 28.09078 Mega-iterations/sec 28.18969 Mega-iterations/sec 28.15002 Mega-iterations/sec 28.23871 Mega-iterations/sec 28.21894 Mega-iterations/sec 28.22879 Mega-iterations/sec 28.16972 Mega-iterations/sec 28.17941 Mega-iterations/sec 27.80536 Mega-iterations/sec 28.17982 Mega-iterations/sec 28.20912 Mega-iterations/sec 28.21900 Mega-iterations/sec 28.22866 Mega-iterations/sec 28.23860 Mega-iterations/sec 28.23893 Mega-iterations/sec 28.20907 Mega-iterations/sec 28.18948 Mega-iterations/sec 28.19925 Mega-iterations/sec 28.14016 Mega-iterations/sec 28.16979 Stopping... Mega-iterations/sec 5.08054 Final accumulator value: 631551148 Final iterations: 1686790000 Bye.
Also ca. 0.25% Impact.
Also ziemlich genau 1/10 von dem was in dem Blog-Beitrag steht. Kommt mir immer noch viel vor, aber naja.System:
Windows 8 amd64, Q6600, 8 GB RAM
"nix" im Hintergrund laufen, Timer Resolution mitclockres.exe
undpowercfg -energy
nachkontrolliert = normal 15.6ms, mittimeBeginPeriod(1)
auf 1ms.
Programm läuft als 32 Bit Prozess (WoW64).Code:
#include <stdio.h> #include <conio.h> #include <thread> #include <Windows.h> #include <boost/random.hpp> #include <boost/lexical_cast.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/preprocessor/stringize.hpp> #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> #pragma comment(lib, "winmm") LARGE_INTEGER g_performanceCounterFrequency; volatile unsigned long g_accumulator; volatile unsigned long g_iterations; volatile long g_break; double GetTime() { LARGE_INTEGER counter; QueryPerformanceCounter(&counter); return counter.QuadPart / double(g_performanceCounterFrequency.QuadPart); } template<class Engine> void WorkerFn(typename boost::enable_if<boost::is_floating_point<typename Engine::result_type>, unsigned>::type blockSize) { Engine generator; generator.seed(); while (!g_break) { unsigned long accumulator = 0; for (unsigned i = 0; i < blockSize; i++) accumulator += static_cast<unsigned long>((generator() + 1.0) * 123456789) & 0xFFFF; ::InterlockedExchangeAdd(&g_accumulator, accumulator); ::InterlockedExchangeAdd(&g_iterations, blockSize); } } template<class Engine> void WorkerFn(typename boost::enable_if<boost::is_integral<typename Engine::result_type>, unsigned>::type blockSize) { Engine generator; generator.seed(); while (!g_break) { unsigned long accumulator = 0; for (unsigned i = 0; i < blockSize; i++) accumulator += generator() & 0xFFFF; ::InterlockedExchangeAdd(&g_accumulator, accumulator); ::InterlockedExchangeAdd(&g_iterations, blockSize); } } void TickerFn() { ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); double time1 = GetTime(); unsigned long iterations1 = ::InterlockedCompareExchange(&g_iterations, 0, 0); while (!g_break) { double time0 = time1; unsigned long iterations0 = iterations1; ::Sleep(1000); time1 = GetTime(); iterations1 = ::InterlockedCompareExchange(&g_iterations, 0, 0); unsigned long deltaIterations = iterations1 - iterations0; double deltaTime = time1 - time0; printf("Mega-iterations/sec %.5f\n", deltaIterations / deltaTime / (1000.0*1000.0)); } } #define ENGINE_DEFINITION_ENTRY(engineName) \ { BOOST_PP_STRINGIZE(engineName), &WorkerFn<boost::engineName> } static struct EngineDefinition { char const* const engineName; void (*workerThreadFn)(unsigned); } const engineDefinitions[] = { ENGINE_DEFINITION_ENTRY(ranlux64_3), ENGINE_DEFINITION_ENTRY(minstd_rand0), ENGINE_DEFINITION_ENTRY(minstd_rand), ENGINE_DEFINITION_ENTRY(rand48), ENGINE_DEFINITION_ENTRY(ecuyer1988), ENGINE_DEFINITION_ENTRY(kreutzer1986), ENGINE_DEFINITION_ENTRY(taus88), ENGINE_DEFINITION_ENTRY(hellekalek1995), ENGINE_DEFINITION_ENTRY(mt11213b), ENGINE_DEFINITION_ENTRY(mt19937), ENGINE_DEFINITION_ENTRY(mt19937_64), ENGINE_DEFINITION_ENTRY(lagged_fibonacci607), ENGINE_DEFINITION_ENTRY(lagged_fibonacci1279), ENGINE_DEFINITION_ENTRY(lagged_fibonacci2281), ENGINE_DEFINITION_ENTRY(lagged_fibonacci3217), ENGINE_DEFINITION_ENTRY(lagged_fibonacci4423), ENGINE_DEFINITION_ENTRY(lagged_fibonacci9689), ENGINE_DEFINITION_ENTRY(lagged_fibonacci19937), ENGINE_DEFINITION_ENTRY(lagged_fibonacci23209), ENGINE_DEFINITION_ENTRY(lagged_fibonacci44497), ENGINE_DEFINITION_ENTRY(ranlux3), ENGINE_DEFINITION_ENTRY(ranlux4), ENGINE_DEFINITION_ENTRY(ranlux64_4), ENGINE_DEFINITION_ENTRY(ranlux3_01), ENGINE_DEFINITION_ENTRY(ranlux4_01), ENGINE_DEFINITION_ENTRY(ranlux64_3_01), ENGINE_DEFINITION_ENTRY(ranlux64_4_01), }; #undef ENGINE_DEFINITION_ENTRY void Run(unsigned threadCount, EngineDefinition const* engineDefinition, unsigned blockSize) { printf("Thread count: %d\n", threadCount); printf("RNG engine: %s\n", engineDefinition->engineName); printf("Block size: %d\n", blockSize); puts("Keys:\n" " 1 ... 9 : request timer resolution of 1 ... 9 milliseconds\n" " 0 : clear timer resolution request\n" " x : exit\n"); QueryPerformanceFrequency(&g_performanceCounterFrequency); ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); std::vector<std::thread> threads; for (unsigned i = 0; i < threadCount; i++) threads.emplace_back(engineDefinition->workerThreadFn, blockSize); threads.emplace_back(&TickerFn); UINT activeResolution = 0; while (!g_break) { int const ch = _getch(); if (ch >= '0' && ch <= '9') { if (activeResolution) { ::timeEndPeriod(activeResolution); activeResolution = 0; } UINT requestedResolution = ch - '0'; if (requestedResolution) { if (::timeBeginPeriod(requestedResolution) != TIMERR_NOERROR) { puts("ERROR: timeBeginPeriod failed."); exit(1); } activeResolution = requestedResolution; printf("Requested timer resolution: %d\n", activeResolution); } else puts("Removed timer resolution request.\n"); } else if (ch == 'x') { puts("Stopping...\n"); g_break = 1; } } for (auto& t : threads) t.join(); printf("Final accumulator value: %ld\n", g_accumulator); printf("Final iterations: %ld\n", g_iterations); puts("Bye.\n"); } void Run(std::vector<std::string> const& args) { unsigned threadCount = std::thread::hardware_concurrency(); unsigned blockSize = 10000; EngineDefinition const* engineDefinition = &engineDefinitions[0]; for (size_t i = 0; i < args.size(); i++) { if (boost::iequals(args[i], "-t")) { threadCount = boost::lexical_cast<unsigned>(args.at(i + 1)); i++; } else if (boost::iequals(args[i], "-b")) { blockSize = boost::lexical_cast<unsigned>(args.at(i + 1)); i++; } else if (boost::iequals(args[i], "-e")) { std::string const engineName = args.at(i + 1); i++; bool found = false; for (auto const& edef : engineDefinitions) { if (boost::iequals(engineName, edef.engineName)) { engineDefinition = &edef; found = true; break; } } if (!found) { printf("ERROR: Unknown engine %s", engineName.c_str()); exit(1); } } else { printf("ERROR: Unknown option %s", args[i].c_str()); exit(1); } } Run(threadCount, engineDefinition, blockSize); } int main(int argc, char* argv[]) { try { Run(std::vector<std::string>(argv + 1, argv + argc)); } catch (std::exception const& e) { printf("ERROR: %s\n (%s)\n", e.what(), typeid(e).name()); exit(1); } }
-
brucedawson schrieb:
Fascinating. I think that means that Windows 8 is only running the timer interrupt on some cores. Or something like that.
-
Die Argumentation ist also, dass Linux unfähig ist Webseiten flüssig anzuzeigen.
OK, das macht Sinn...
-
Shade Of Mine schrieb:
Die Argumentation ist also, dass Linux unfähig ist Webseiten flüssig anzuzeigen.
OK, das macht Sinn...
-
mint schrieb:
Komischerweise kommt Linux doch auch mit einer festen Tick-Rate aus, die sich nicht zur Laufzeit ändern lässt. Und kann auch Multimedia ganz gut.
Inzwischen gibt es nicht mal mehr feste ticks: https://lwn.net/Articles/549580/
-
und davor waren sie auf 250 mal pro Sekunde
-
mega confused schrieb:
Shade Of Mine schrieb:
Die Argumentation ist also, dass Linux unfähig ist Webseiten flüssig anzuzeigen.
OK, das macht Sinn...
Du kannst die Timer Auflösung in Linux nicht ändern. Ergo kann nur Windows flüssig eine HTML Seite darstellen - denn unter Windows ist es ja notwendig die Timer Auflösung für HTML Seiten zu ändern da sie sonst nicht flüssig dargestellt werden können. Linux bietet diese Option nicht, ergo ist Linux zum surfen ungeeignet.
-
Shade Of Mine schrieb:
mega confused schrieb:
Shade Of Mine schrieb:
Die Argumentation ist also, dass Linux unfähig ist Webseiten flüssig anzuzeigen.
OK, das macht Sinn...
Du kannst die Timer Auflösung in Linux nicht ändern. Ergo kann nur Windows flüssig eine HTML Seite darstellen - denn unter Windows ist es ja notwendig die Timer Auflösung für HTML Seiten zu ändern da sie sonst nicht flüssig dargestellt werden können. Linux bietet diese Option nicht, ergo ist Linux zum surfen ungeeignet.
Linux kann Internetseiten flüssig darstellen da es defaultmässig mit timeBeginPeriod(4) oder timeBeginPeriod(10) läuft.
-
bullshit! schrieb:
Linux kann Internetseiten flüssig darstellen da es defaultmässig mit timeBeginPeriod(4) oder timeBeginPeriod(10) läuft.
Das ist aber zu langsam. timeBeginPeriod(1) ist notwendig, sonst ruckelt alles ja furchtbar.
-
da ist wohl jemand auf ärger aus...
-
citrus schrieb:
und davor waren sie auf 250 mal pro Sekunde
Davor waren sie das was die jeweilige Distro verwendet hat. Auf bestimmten SUSE Versionen waren es konstant 1000 Hz.
-
Shade Of Mine schrieb:
Die Argumentation ist also, dass Linux unfähig ist Webseiten flüssig anzuzeigen.
OK, das macht Sinn...
Hat das jemand behauptet?
-
quoter schrieb:
brucedawson schrieb:
Fascinating. I think that means that Windows 8 is only running the timer interrupt on some cores. Or something like that.
Auf Win7 kann ich erst morgen testen.