24 September, 2008

Эволюция ошибок

Сегодня было проведены полномаштабные dotTrace-маневры в обстановке приближенной к боевой. Незамедлительно я отметил для себя удивительную закономерность: предыдущая версия частенько кидала "Out of Memory" (эта стандартная болезнь почти всех профайлеров), а новая похоже будет частенько кидать "Low Disk Space"... Не смешно! Как вам размер снапшотика в 36 Гигабайт? А ведь это всего 20% теста... Другими словами, снапшотик в 180 Гигабайт - это наша объективная реальность. Не смешно, два раза! С другой стороны, один снапшот - это один винчестер. На лицо удобство транспортировки...

P.S. А теперь скажем об этом официально.

API из песка и тумана

Кривые ручка отдельного програмиста - это дело его босса, а вот кривые ручки одной из команд MS - это уже дело каждого. Особенно, если кривость увековечена в WinSDK. Итак, приступим. Постоянно ковыряясь в ассемблере x86 и x64 я заметил, что InterlockXXX функции в x86 - это вызовы API, а в x64 - просто команды ассемблера. Ошибкой было бы думать, что это трагическая случайность. И действительно для x64 и IPF в WinSDK по умочанию сделаны специальные intrinsic-мактосы, а про платформу x86 попросту забыли. Ну не совсем забыли конечно - все можно включить, но это требует некоторого умения и сноровки. Переопределение InterlockedExchangePointer и InterlockedCompareExchangePointer сделано не случайно - без оного мы опять получаем вызовы API вместо ассемблерной команды.

#if defined(_M_IX86)
  #include "intrin.h"
 
  #define InterlockedIncrement _InterlockedIncrement
  #define InterlockedDecrement _InterlockedDecrement
  #define InterlockedExchange _InterlockedExchange
  #define InterlockedCompareExchange _InterlockedCompareExchange
 
  #undef InterlockedExchangePointer
  #define InterlockedExchangePointer(T, V) ((PVOID) InterlockedExchange((PLONG) (T), (LONG) (V)))
 
  #undef InterlockedCompareExchangePointer
  #define InterlockedCompareExchangePointer(D, E, C) ((PVOID) InterlockedCompareExchange((PLONG) (D), (LONG) (E), (LONG) (C)))
#endif

Зачем же я все это говорю, если и так и так все работает. Да вы наверно уже обо всем догадались - ассемблерные команды сильно быстрее. На моем приложении прирост на пустом месте составил более 5%.