Что самый быстрый путь состоит в том, чтобы преобразовать плавание в интервал на x86

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

22
задан kristianp 2 May 2012 в 04:20
поделиться

8 ответов

Это зависит от того, если Вы хотите преобразование усечения или округляющееся и в какой точность. По умолчанию C выполнит преобразование усечения, когда Вы пойдете от плавания до интервала существуют инструкции по FPU, которые делают это, но это не ANSI C преобразование и существуют значительные протесты к использованию его (такие как знание состояния округления FPU). Так как ответ на Вашу проблему довольно сложен и зависит от некоторых переменных, которые Вы не выразили, я рекомендую эту статью о проблеме:

http://www.stereopsis.com/FPU.html

17
ответ дан Zach Burlingame 29 November 2019 в 03:50
поделиться

Упакованное преобразование с помощью SSE является безусловно самым быстрым методом, так как можно преобразовать несколько значений в той же инструкции. ffmpeg имеет большой блок для этого (главным образом для преобразования декодируемого вывода аудио к целочисленным образцам); проверьте его на некоторые примеры.

13
ответ дан Matthieu 29 November 2019 в 03:50
поделиться

Наиболее часто используемый прием для плоскости x86/x87 код должен вынудить часть мантиссы плавания представить международную версию на 32 бита, следует.

64-разрядная версия аналогична. Версия Lua, отправленная выше, быстрее, но полагается на усечение дважды к 32-разрядному результату, поэтому это требует, чтобы x87 единица была установлена на двойную точность и не может быть адаптировано к дважды к 64-разрядному международному преобразованию.

хорошая вещь об этом коде - он, является абсолютно портативным для всех платформ, соответствующих IEEE 754, единственное сделанное предположение является режимом округления плавающей точки, установлен на самый близкий.Примечание: Портативный в смысле это компилирует и работает. Платформы кроме x86 обычно не извлекают выгоду очень из этой техники, если вообще.

static const float Snapper=3<<22;

union UFloatInt {
 int i;
 float f;
};

/** by Vlad Kaipetsky
portable assuming FP24 set to nearest rounding mode
efficient on x86 platform
*/
inline int toInt( float fval )
{
  Assert( fabs(fval)<=0x003fffff ); // only 23 bit values handled
  UFloatInt &fi = *(UFloatInt *)&fval;
  fi.f += Snapper;
  return ( (fi.i)&0x007fffff ) - 0x00400000;
}
9
ответ дан finnw 29 November 2019 в 03:50
поделиться

Если можно гарантировать, что ЦП, выполняющий код, SSE3 совместимый (даже Pentium 5, JBB), можно позволить компилятору использовать свою инструкцию FISTTP (т.е.-msse3 для gcc). Это, кажется, делает, вещь как он должна была всегда делаться:

http://software.intel.com/en-us/articles/how-to-implement-the-fisttp-streaming-simd-extensions-3-instruction/

Примечание, что FISTTP отличается от FISTP (который имеет его проблемы, вызывая замедление). Это стало частью SSE3, но является на самом деле (единственное) улучшением X87-стороны.

Другой тогда ЦП X86, вероятно, сделал бы преобразование очень хорошо, так или иначе.:)

Процессоры с поддержкой SSE3

7
ответ дан akauppi 29 November 2019 в 03:50
поделиться

Кодовая база Lua имеет следующий отрывок, чтобы сделать это (регистрация src/luaconf.h с www.lua.org). Если бы Вы находите (ПОЭТОМУ находит), более быстрый путь, я уверен, что они были бы взволнованы.

, О, lua_Number средства дважды.:)

/*
@@ lua_number2int is a macro to convert lua_Number to int.
@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
** CHANGE them if you know a faster way to convert a lua_Number to
** int (with any rounding method and without throwing errors) in your
** system. In Pentium machines, a naive typecast from double to int
** in C is extremely slow, so any alternative is worth trying.
*/

/* On a Pentium, resort to a trick */
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
    (defined(__i386) || defined (_M_IX86) || defined(__i386__))

/* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER)

#define lua_number2int(i,d)   __asm fld d   __asm fistp i
#define lua_number2integer(i,n)     lua_number2int(i, n)

/* the next trick should work on any Pentium, but sometimes clashes
   with a DirectX idiosyncrasy */
#else

union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) \
  { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n)     lua_number2int(i, n)

#endif

/* this option always works, but may be slow */
#else
#define lua_number2int(i,d) ((i)=(int)(d))
#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))

#endif
6
ответ дан phuclv 29 November 2019 в 03:50
поделиться

Существует одна инструкция преобразовать плавающую точку в интервал в блоке: используйте инструкцию FISTP. Это выталкивает значение от стека с плавающей точкой, преобразовывает его в целое число, и затем хранит в в определенном адресе. Я не думаю, что был бы более быстрый путь (если Вы не используете расширенные системы команд как MMX или SSE, который я не знаком с).

Другая инструкция, КУЛАК, оставляет значение на стеке FP, но я не уверен, что это работает с измеренными местами назначения квадратического слова.

6
ответ дан dreamlax 29 November 2019 в 03:50
поделиться

Если Вы действительно заботитесь о скорости этого, удостоверяются, что Ваш компилятор генерирует инструкцию по КУЛАКУ. В MSVC можно сделать, это с/QIfist, видит этот обзор

MSDN, можно также рассмотреть использование SSE intrinsics, чтобы сделать работу для Вас, видеть эту статью от Intel: http://softwarecommunity.intel.com/articles/eng/2076.htm

3
ответ дан Don Neufeld 29 November 2019 в 03:50
поделиться

Обычно можно доверять компилятору, чтобы быть эффективными и корректными. Обычно нет ничего, чтобы быть полученным путем прокрутки собственных функций для чего-то, что уже существует в компиляторе.

-7
ответ дан user14504 29 November 2019 в 03:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: