На 32-разрядных процессорах, является «целым» типом более эффективным, чем «короткий» тип? -- architecture поле с участием integer поле с участием cpu поле с участием 32-bit поле с участием cpu-architecture пол Связанный проблема

On 32-bit CPUs, is an 'integer' type more efficient than a 'short' type?


9
vote

проблема

русский

на 32-разрядном процессоре, целое число составляет 4 байта, а короткое целое число составляет 2 байта. Если я пишу приложение C / C ++, которое использует многие числовые значения, которые всегда будут вписываться в прилагаемый диапазон короткого целочисленного числа, это более эффективно использовать 4 байтовных целых чисел или 2 байтовых целых числа?

Я слышал, что это предположило, что 4 байтовых целых числа более эффективны, так как это соответствует пропускной способности шины от памяти в процессор. Однако, если я добавляю вместе два коротких целых числа, будет пакет процессора оба значения в одном проходе параллельно (таким образом, охватывает 4 байтовой пропускной способности шины)?

Английский оригинал

On a 32-bit CPU, an integer is 4 bytes and a short integer is 2 bytes. If I am writing a C/C++ application that uses many numeric values that will always fit within the provided range of a short integer, is it more efficient to use 4 byte integers or 2 byte integers?

I have heard it suggested that 4 byte integers are more efficient as this fits the bandwidth of the bus from memory to the CPU. However, if I am adding together two short integers, would the CPU package both values in a single pass in parallel (thus spanning the 4 byte bandwidth of the bus)?

</div
              
   
   

Список ответов

14
 
vote
vote
Лучший ответ
 

Да, вы должны определенно использовать 32-битное целое число на 32-разрядном процессоре, в противном случае он может в конечном итоге замаскировать неиспользуемые биты (т. Е. Он всегда будет делать математики в 32 битах, затем преобразовать ответ на 16 бит)

Это не будет делать два 16-битных операции одновременно для вас, но если вы сами пишете код, и вы уверены, что он не будет переполнен, вы можете сделать это самостоятельно.

Редактировать : Я должен добавить, что он также несколько зависит от вашего определения «эффективного». Хотя он сможет сделать 32-битные операции быстрее, вы, конечно, будете использовать в два раза больше памяти.

Если они используются для промежуточных расчетов во внутренней петле где-то, то используйте 32-битное. Если, однако, вы читаете это с диска или даже если вам просто нужно платить за пропустить кэш, он может работать лучше использовать 16-битные целые числа. Как и во всех оптимизациях, есть только один способ узнать: профиль это .

 

Yes, you should definitely use a 32 bit integer on a 32 bit CPU, otherwise it may end up masking off the unused bits (i.e., it will always do the maths in 32 bits, then convert the answer to 16 bits)

It won't do two 16 bit operations at once for you, but if you write the code yourself and you're sure it won't overflow, you can do it yourself.

Edit: I should add that it also depends somewhat on your definition of "efficient". While it will be able to do 32-bit operations more quickly, you will of course use twice as much memory.

If these are being used for intermediate calculations in an inner loop somewhere, then use 32-bit. If, however, you're reading this from disk, or even if you just have to pay for a cache miss, it may still work out better to use 16-bit integers. As with all optimizations, there's only one way to know: profile it.

</div
 
 
 
 
16
 
vote

Если у вас есть большой массив номеров, то перейдите с наименьшим размером, который работает. Это будет более эффективно работать с массивом 16-битных шортров, чем 32 бит INT, так как вы получите дважды плотность кэша. Стоимость любого расширения знака ЦП должен сделать, чтобы работать с 16-битными значениями в 32-битных регистрах, тривециально незначительно по сравнению с стоимостью промывки кэша.

Если вы просто используете переменные элементов в классах, смешанных с другими типами данных, то менее четко разрезается, поскольку требования к дому, скорее всего, удалят любые преимущества космического пространства 16-битных значений.

 

If you have a large array of numbers, then go with the smallest size that works. It will be more efficient to work with an array of 16 bit shorts than 32 bit ints since you get twice the cache density. The cost of any sign extension the CPU has to do to work with 16 bit values in 32 bit registers is trivially negligible compared to the cost of a cache miss.

If you are simply using member variables in classes mixed with other data types then it is less clear cut as the padding requirements will likely remove any space saving benefit of the 16 bit values.

</div
 
 
4
 
vote

32-битный CPU - это процессор, который обычно работает на 32-битных значениях внутренне, но это не означает, что он медленнее при выполнении той же операции на 8/16 битном значении. X86 Например, еще обратно совместим до 8086, может работать на фракциях реестра. Это означает, что даже если реестр широко используется 32 бит, он может работать только на первом 16 или первом 8 бит этого регистра, и вообще не будет замедляться. Эта концепция даже была принята X86_64, где регистры составляют 64 бита, но они все еще могут работать только на первом 32, 16 или 8 битах.

также процессоры x86 всегда загружают целую строку кэша из памяти, если она еще не в кэше, и строка кэша больше, чем 4 байта (для 32-разрядных процессоров, скорее 8 или 16 байтов) и, таким образом, загрузка 2 байта из памяти одинаково быстро, как загрузка 4 байта из памяти. При обработке многих значений из памяти 16 битных значений могут на самом деле быть намного быстрее, чем 32-битные значения, поскольку есть меньше переводов памяти. Если строка кэша составляет 8 байтов, есть четыре 16-битных значения на одну строку кэша, но только два 32-битных значения, таким образом, при использовании 16 бит INT у вас есть один доступ к памяти каждые четыре значения, используя 32 бит INT, у вас есть один каждые два значения в результате чего в два раза больше передачи для обработки большого int Arri.

Другие процессоры, такие как PPC, например, не могут обрабатывать только долю реестра, они всегда обрабатывают полный регистр. Тем не менее, эти процессоры обычно имеют специальные операции нагрузки, которые позволяют им, например, Загрузите 16-битное значение из памяти, разверните его до 32 бита и запишите его в реестр. Позже у них есть специальная операция магазина, которая принимает значение из реестра и только хранит последние 16 бит назад к памяти; Оба операции нужна только один цикл ЦП, так же, как 32-битная нагрузка / магазин, поэтому также нет разницы скорости. И поскольку PPC может выполнять только арифметические операции на регистры (в отличие от x86, которая также может работать непосредственно в памяти), эта процедура нагрузки / магазина все равно имеет место, используете ли вы 32 бит INT или 16 бит INT.

Единственный недостаток, если вы цепите несколько операций на 32-разрядном процессоре, который может работать только на полных регистрах, заключается в том, что 32-битный результат последней операции, возможно, должен быть «вырезать» на 16 бит до следующей операции выполняется, в противном случае результат может быть не правильным. Такая срезанная спина - это только один цикл CPU, хотя (простой и операция), и компиляторы очень хороши на выяснении, когда такая отрезанная спина действительно необходима, а при оказании его не будет никакого влияния на конечный результат Таким образом, такая срезанная спина не выполняется после каждой инструкции, она выполняется только в том случае, только если действительно неизбежно. Некоторые процессоры предлагают различные «расширенные» инструкции, которые делают такое сокращение ненужным, и я видел множество кодов в моей жизни, где я ожидал, что такое сокращение обратно, но смотрите на сгенерированный код сборки, компилятор нашел путь к Избегайте его целиком.

Так что, если вы ожидаете общего правила здесь, мне придется разочаровать вас. Никто не может никому сказать, что 16-битные операции одинаково быстро до 32-битных операций, и никто не может сказать, что 32-битные операции всегда будут быстрее. Это зависит от того, что именно ваш код делает с этими числами и как это делает это. Я видел ориентиры, где 32-битные операции были быстрее на определенных 32-разных процессорах, чем один и тот же код с 16-битной операцией, однако я также уже видел, что напротив наоборот. Даже переключение с одного компилятора на другое или обновление вашей версии компилятора, возможно, уже снова включает все вокруг. Я могу только сказать следующее: кто претендует на то, что работа с шортами значительно медленнее, чем работать с INTS, предоставляют исходный код образца для этого претензии и названия CPU и компилятора, который он использовал для Testi G, так как я никогда не испытывал ничего подобного в течение последних 10 лет. Могут быть некоторые ситуации, где работает с Int Maints, может быть, на 1-5% быстрее, но что-то ниже 10% не «значительно», и вопрос в том, стоит ли тратить в два раза память в некоторых случаях только потому, что это может купить вам 2% производительности? Я так не думаю.

 

A 32 bit CPU is a CPU that usually operates on 32 bit values internally, yet that does not mean that it is any slower when performing the same operation on a 8/16 bit value. x86 for example, still backward compatible up to the 8086, can operate on fractions of a register. That means even if a register is 32 bit wide, it can operate only on the first 16 or the first 8 bit of that register and there will be no slow down at all. This concept has even been adopted by x86_64, where the registers are 64 bit, yet they still can operate only on the first 32, 16, or 8 bit.

Also x86 CPUs always load a whole cache line from memory, if not already in cache, and a cache line is bigger than 4 byte anyway (for 32 bit CPUs rather 8 or 16 bytes) and thus loading 2 byte from memory is equally fast as loading 4 byte from memory. If processing many values from memory, 16 bit values may actually be much faster than 32 bit values, since there are less memory transfers. If a cache line is 8 byte, there are four 16 bit values per cache line, yet only two 32 bit values, thus when using 16 bit ints you have one memory access every four values, using 32 bit ints you have one every two values, resulting in twice as many transfers for processing a large int array.

Other CPUs, like PPC for example, cannot process only a fraction of a register, they always process the full register. Yet these CPUs usually have special load operations that allow them to, e.g. load a 16 bit value from memory, expand it to 32 bit and write it to a register. Later on they have a special store operation that takes the value from the register and only stores the last 16 bit back to memory; both operation need only one CPU cycle, just like a 32 bit load/store would need, so there is no speed difference either. And since PPC can only perform arithmetic operations on registers (unlike x86, which can also operate on memory directly), this load/store procedure takes place anyway whether you use 32 bit ints or 16 bit ints.

The only disadvantage, if you chain multiple operations on a 32 bit CPU that can only operate on full registers, is that the 32 bit result of the last operation may have to be "cut back" to 16 bit before the next operation is performed, otherwise the result may not be correct. Such a cut back is only a single CPU cycle, though (a simple AND operation), and compilers are very good at figuring out when such a cut back is really necessary and when leaving it out won't have any influence on the final result, so such a cut back is not performed after every instruction, it is only performed if really unavoidable. Some CPUs offers various "enhanced" instructions which make such a cut back unnecessary and I've seen plenty of code in my life, where I had expected such a cut back, yet looking at the generated assembly code, the compiler found a way to avoid it entirely.

So if you expect a general rule here, I'll have to disappoint you. Neither can one say for sure that 16 bit operations are equally fast to 32 bit operations, nor can anyone say for sure that 32 bit operations will always be faster. It depends also what exactly your code is doing with those numbers and how it is doing that. I've seen benchmarks where 32 bit operations were faster on certain 32 bit CPUs than the same code with 16 bit operations, however I also already saw the opposite being true. Even switching from one compiler to another one or upgrading your compiler version may already turn everything around again. I can only say the following: Whoever claims that working with shorts is significantly slower than working with ints, shall please provide a sample source code for that claim and name CPU and compiler he used for testing, since I have never experienced anything like that within about the past 10 years. There may be some situations, where working with ints is maybe 1-5% faster, yet anything below 10% is not "significant" and the question is, is it worth to waste twice the memory in some cases only because it may buy you 2% performance? I don't think so.

</div
 
 
     
     
8
 
vote

Если вы используете «много» целочисленных значений, узкое место в вашей обработке может быть связана с пропускной способностью к памяти. 16 бит целых чисел более плотно в кэш данных, и поэтому будет выиграть производительность.

Если вы номера хрустания на очень большом количестве данных, вы должны прочитать Что каждый программист должен Знайте о памяти Ульрихом Дреппер. Сосредоточиться в главе 6, о максимизации эффективности кэша данных.

 

If you're using "many" integer values, the bottleneck in your processing is liable to be bandwidth to memory. 16 bit integers pack more tightly into the data cache, and would therefore be a performance win.

If you are number crunching on a very large amount of data, you should read What Every Programmer Should Know About Memory by Ulrich Drepper. Concentrate on chapter 6, about maximizing the efficiency of the data cache.

</div
 
 
3
 
vote

Это зависит. Если вы ограничите CPU, 32-битные операции на 32-разрядном процессоре будут быстрее, чем 16 бит. Если вы связаны с памятью (в частности, если у вас слишком много пропущений кэша L2), затем используйте самые маленькие данные, которые вы можете выжать.

Вы можете узнать, какой из них используете профилировщик, который будет измерять как CPU, так и L2 пропускания, как VTUNE Intel . Вы запустите свое приложение 2 раза с той же нагрузкой, и он будет объединять 2 пробежки в одно представление о горячих точках в вашем приложении, и вы можете увидеть каждую строку кода, сколько циклов было потрачено на эту строку. Если у дорогих строки кода вы видите 0 кэш-пропуске, вы ограничите CPU. Если вы видите тонны пропускания, вы связаны с памятью.

 

It depends. If you are CPU bound, 32 bit operations on a 32 bit CPU will be faster than 16 bit. If you are memory bound (specifically if you have too many L2 cache misses), then use the smallest data you can squeeze into.

You can find out which one you are using a profiler that will measure both CPU and L2 misses like Intel's VTune. You will run your app 2 times with the same load, and it will merge the 2 runs into one view of the hotspots in your app, and you can see for each line of code how many cycles were spent on that line. If at an expensive line of code, you see 0 cache misses, you are CPU bound. If you see tons of misses, you are memory bound.

</div
 
 
3
 
vote

Не слушайте советы, попробуйте.

Это, вероятно, будет сильно зависеть от аппаратного / компилятора, который вы используете. Быстрый тест должен сделать короткую работу этого вопроса. Вероятно, меньше времени, чтобы написать тест, чем писать вопрос здесь.

 

Don't listen to the advice, try it.

This is probably going to depend heavily on the hardware/compiler that you're using. A quick test should make short work of this question. Probably less time to write the test than it is to write the question here.

</div
 
 
1
 
vote

Если вы работаете в большом наборе данных, самая большая проблема - след памяти. Хорошая модель в этом случае состоит в том, чтобы предположить, что ЦП бесконечно быстрый, и тратить время на беспокойство о том, сколько данных должно быть перемещено в / из памяти. Фактически, процессоры теперь настолько быстро, что иногда более эффективно кодировать (например, сжатие). Таким образом, процессор (потенциально много) больше работы (декодирование / кодирование), но ширина полосы памяти существенно снижается.

Таким образом, если ваш набор данных большой, вам, вероятно, лучше использовать 16 бит целых чисел. Если ваш список отсортирован, вы можете разработать схему кодирования, которая включает в себя дифференциал или кодировку длины запуска, что еще больше снизит пропускную способность памяти.

 

If you are operating on a large dataset, the biggest concern is memory footprint. A good model in this case is to assume that the CPU is infinitely fast, and spend your time worrying about how much data has to be moved to/from memory. In fact, CPUs are now so fast that it is sometimes more efficient to encode (e.g., compress) the data. That way, the CPU does (potentially much) more work (decoding/coding), but the memory bandwidth is substantially reduced.

Thus, if your dataset is large, you are probably better off using 16 bit integers. If your list is sorted, you might design a coding scheme that involves differential or run-length encoding, which will reduce memory bandwidth even more.

</div
 
 
0
 
vote

Когда вы говорите 32 бит, я предполагаю, что вы имеете в виду x86. 16-битная арифметика довольно медленная: префикс размера операнда делает декодирование действительно медленно. Так что не делайте ваши переменные TEMP STOR INT или INT16_T.

Однако x86 может эффективно нагружать 16 и 8 бит целых чисел на 32 или 64-битных регистрах. (movzx / movsx: нулевое и растяжение знака). Так что не стесняйтесь использовать короткие int для массивов и структурных полей, но убедитесь, что вы используете Int или Long для ваших переменных TEMP.

Однако, если я добавляю вместе две короткие целыми числами, наберуте CPU оба значения в одном проходе параллельно (таким образом, охватывает 4 байта полосы пропускания шины)?

Это ерунда. Инструкции нагрузки / магазина взаимодействуют с кэшем L1, а ограничивающий коэффициент является ряд OPS; ширина не имеет значения. например На Core2: 1 нагрузка и 1 магазин на цикл, независимо от ширины. Кэш L1 имеет 128 или 256-битный путь к кэше L2.

Если нагрузки - это узкое место, одна широкая нагрузка, которую вы расстались с сдвигами или масками после загрузки, могут помочь. Или используйте SIMD для обработки данных параллельно без распаковки после загрузки параллельно.

 

When you say 32bit, I'll assume you mean x86. 16 bit arithmetic is quite slow: the operand-size prefix makes decoding really slow. So don't make your temp variables short int or int16_t.

However, x86 can efficiently load 16 and 8 bit integers into 32 or 64 bit registers. (movzx / movsx: zero and sign extension). So feel free to use short int for arrays and struct fields, but make sure you use int or long for your temp variables.

However, if I am adding together two short integers, would the CPU package both values in a single pass in parallel (thus spanning the 4 byte bandwidth of the bus)?

That is nonsense. load/store instructions interact with L1 cache, and the limiting factor is number of ops; width is irrelevant. e.g. on core2: 1 load and 1 store per cycle, regardless of width. L1 cache has a 128 or 256bit path to L2 cache.

If loads are your bottleneck, one wide load which you split up with shifts or masks after loading can help. Or use SIMD to process data in parallel without unpacking after loading in parallel.

</div
 
 

Связанный проблема

2  Лучшие практики для настройки первоначальной среды снежинки - несколько URL  ( Best practices for setting up initial snowflake environment multiple urls ) 
Я хотел бы знать, как другие настроили свою первоначальную среду снежинки с соображениями для DEVOPS и развертываний кода и их опытом в этом. Люди используют ...

0  Диаграмма архитектуры решения - направления стрелки  ( Solution architecture diagram arrow directions ) 
Есть разные типы стрелок, используемых в диаграммах архитектуры программного обеспечения. для бывшего. Есть два приложения A и B. В чем разница между следую...

0  Как вы загружаете файл JavaScript в объем  ( How do you load a javascript file into a scope ) 
Я пытаюсь выяснить, как загрузить содержимое файла JavaScript в объем. Причина этого я хочу иметь возможность иметь возможности подключения и воспроизведения ...

1  Может ли libPCAP быть скомпилирован для iPhone / ARMV6?  ( Can libpcap be compiled for iphone armv6 ) 
Попытка компилировать базовую программу, которая использует PCAP.h. Я настроил среду на моей коробке Mac OSX, которая использует SDK iPhone 3.1.3 для iPhone 3...

3  Совершенно JavaScript Web Stage - промежуточное программное обеспечение, веб-сервер, DB предложений?  ( Totally javascript web stack middleware webserver db suggestions ) 
Я в настоящее время ищу новый веб-стек, чтобы построить проект хобби и хотелось бы, чтобы он был включен в JavaScript. У меня был быстрый взгляд на NITRO, NAR...

-1  Модульный монолит с DDD и устаревшими данными  ( Modular monolith with ddd and legacy data ) 
В моем домене у меня есть следующие модули: WMS (управление складом) Спросальдер (содержит продавщику, и т. Д.) Это приложение Multi Managaness, что означае...

13  Дублирующие символы для архитектуры ARM64 после обновления Xcode 8.0  ( Duplicate symbols for architecture arm64 after xcode 8 0 update ) 
Я получаю дублирующие символы ошибки после обновления мой <код> Xcode . (Найти код вниз). Кто-нибудь тоже получает это? И как можно решить? Я пытался удалит...

7  При разработке программной платформы, какие ключевые элементы составляют успешную сменутую архитектуру? [закрыто]  ( When designing a software platform what are the key elements that make up a suc ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> закрыт . Этот вопрос должен быть больше Фокусированный . В настоя...

0  Архитектура моего приложения - 1 просмотр спрашивает «иностранную» модель  ( Architecture of my application 1 view asks for a foreign model ) 
У меня есть 2 приложения: учетные записи Ant Contons. Мои «учетные записи» приложение касается учетных записей пользователей простым моделью: <код> class ...

1  Архитектура для моделирования  ( Architecture for modeling ) 
Общее решение для создания модели системы, состоит из многих элементов разных типов, заключается в создании модульной системы, где каждый модуль отвечает за о...

2  Одноместный модульный компонент должен работать с другими компонентами (компонент = модуль)  ( Single modular component should work with other components component module ) 
У меня есть вопрос, но я не уверен, как описать его правильно, пожалуйста, прочитайте осторожность. Во-первых, давайте определим термин модуль в моих глазах: ...

2  Как выбрать дизайн платформа для продукта?  ( How to choose design platform for a product ) 
У меня есть идея для продукта, который будет использоваться у AM Chancial. Я хотел бы иметь веб-приложение с автономным режимом возможности. Нота, я также хоч...

0  Itunes app Загрузить ошибку  ( Itunes app upload error ) 
Я сталкиваюсь с проблемой при загрузке приложения в iTunes Store I.e Ошибка ITMS-90086: «Отсутствующая 64-битная поддержка. IOS Apps, отправленные в App Stor...

0  Воспользуйтесь стратегической структурой Сервисный слой с использованием пружинных данных JPA  ( Implement strategy pattern service layer using spring data jpa ) 
У нас есть следующая структура БД для многих модулей в БД. DB Table A - главная таблица, и есть несколько расширений этой таблицы (B, C, D и т. Д.), Без пер...

1  Запуск кода для модулей Javascript  ( Launching code for javascript modules ) 
<Р> Большинство Javascript I работы с это код UI. - код, который присоединяет дополнительные функциональные возможности в HTML рамках моих страниц и взаимодейс...

Связанный проблема

2  Лучшие практики для настройки первоначальной среды снежинки - несколько URL 
0  Диаграмма архитектуры решения - направления стрелки 
0  Как вы загружаете файл JavaScript в объем 
1  Может ли libPCAP быть скомпилирован для iPhone / ARMV6? 
3  Совершенно JavaScript Web Stage - промежуточное программное обеспечение, веб-сервер, DB предложений? 
-1  Модульный монолит с DDD и устаревшими данными 
13  Дублирующие символы для архитектуры ARM64 после обновления Xcode 8.0 
7  При разработке программной платформы, какие ключевые элементы составляют успешную сменутую архитектуру? [закрыто] 
0  Архитектура моего приложения - 1 просмотр спрашивает «иностранную» модель 
1  Архитектура для моделирования 
2  Одноместный модульный компонент должен работать с другими компонентами (компонент = модуль) 
2  Как выбрать дизайн платформа для продукта? 
0  Itunes app Загрузить ошибку 
0  Воспользуйтесь стратегической структурой Сервисный слой с использованием пружинных данных JPA 
1  Запуск кода для модулей Javascript 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.