Добавление к ответу @wim (который является хорошим ответом ) и принятие во внимание комментария @Bathsheba, стоит того, чтобы доверять компилятору , но также проверять, на что выводит ваш компилятор оба учатся тому, как это делать, а также проверяют, что это делает то, что вы хотите. Выполнение слегка измененной версии вашего кода через godbolt (для msvc, gcc и clang) дает некоторые не идеальные ответы.
Это особенно верно, если вы ограничиваете себя SSE2 и ниже, что предполагает этот ответ (и то, что я проверял)
Все компиляторы как векторизируют, так и разворачивают код и используют punpcklbw
«распаковать» uint8_t
в uint16_t
, а затем запустить добавление и сохранение SIMD. Это хорошо. Однако MSVC имеет тенденцию излишне разливаться во внутреннем цикле, и clang использует только punpcklbw
, а не punpckhbw
, что означает, что он загружает исходные данные дважды. GCC получает правильную часть SIMD, но имеет более высокие издержки для ограничений цикла.
Так что теоретически, если вы хотите улучшить эти версии, вы можете свернуть свою собственную, используя встроенные функции, которые будут выглядеть примерно так:
static inline void adder2(uint16_t *canvas, uint8_t *addon, uint64_t count)
{
uint64_t count32 = (count / 32) * 32;
__m128i zero = _mm_set_epi32(0, 0, 0, 0);
uint64_t i = 0;
for (; i < count32; i+= 32)
{
uint8_t* addonAddress = (addon + i);
// Load data 32 bytes at a time and widen the input
// to `uint16_t`'sinto 4 temp xmm reigsters.
__m128i input = _mm_loadu_si128((__m128i*)(addonAddress + 0));
__m128i temp1 = _mm_unpacklo_epi8(input, zero);
__m128i temp2 = _mm_unpackhi_epi8(input, zero);
__m128i input2 = _mm_loadu_si128((__m128i*)(addonAddress + 16));
__m128i temp3 = _mm_unpacklo_epi8(input2, zero);
__m128i temp4 = _mm_unpackhi_epi8(input2, zero);
// Load data we need to update
uint16_t* canvasAddress = (canvas + i);
__m128i canvas1 = _mm_loadu_si128((__m128i*)(canvasAddress + 0));
__m128i canvas2 = _mm_loadu_si128((__m128i*)(canvasAddress + 8));
__m128i canvas3 = _mm_loadu_si128((__m128i*)(canvasAddress + 16));
__m128i canvas4 = _mm_loadu_si128((__m128i*)(canvasAddress + 24));
// Update the values
__m128i output1 = _mm_add_epi16(canvas1, temp1);
__m128i output2 = _mm_add_epi16(canvas2, temp2);
__m128i output3 = _mm_add_epi16(canvas3, temp3);
__m128i output4 = _mm_add_epi16(canvas4, temp4);
// Store the values
_mm_storeu_si128((__m128i*)(canvasAddress + 0), output1);
_mm_storeu_si128((__m128i*)(canvasAddress + 8), output2);
_mm_storeu_si128((__m128i*)(canvasAddress + 16), output3);
_mm_storeu_si128((__m128i*)(canvasAddress + 24), output4);
}
// Mop up
for (; i(addon[i]);
}
Изучение выходных данных для этого строго лучше, чем у любого из gcc / clang / MSVC. Так что если вы хотите получить абсолютную последнюю каплю перфекта (и иметь фиксированную архитектуру), то возможно что-то подобное вышеописанному. Однако это действительно небольшое улучшение, так как компиляторы уже справляются с этим почти идеально , и поэтому я бы порекомендовал не делать этого и просто доверять компилятору.
Если вы думаете, что можете улучшить компилятор, не забывайте всегда проверять и профилировать, чтобы убедиться, что вы на самом деле.
Try following:
\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
. Edit:
Regarding drivers, check this site: Oracle Instant Client. There you will find documentation on minimum drivers installation needed for JDBC access to Oracle. I don't know much about that because I use .Net.
Edit 2:
See this question: NLS_LANG setting for JDBC thin driver. There is same error as you have and problem was that default locale for NLS LANG was not defined. Quote:
The NLS_LANG settings are derived from the java.util.Locale . Therefore, you will need to make a call similar to this before connecting:
Locale.setDefault(Locale.<your locale here>);
Я понял, что вы можете передать эти два параметра в свое приложение Java, чтобы решить проблему:
-Duser.country=en -Duser.language=en
Вы можете настроить значения на уровне переменных среды также (зависит от вашей ОС).
Если Вы компилируете с intelljIDE, я советую добавить следующие опции в VMoptions, найденном в модели
AddVMOption -Duser.region=us.
конфигураций Изменение настроек региона и языка моей машины помогло сойти с рук это. Я изменил регион на Соединенные Штаты и английский язык (Соединенные Штаты) как язык.
Я нашел решение, я просто меняю регион и язык в своей ОС (Windows 7), убедитесь, что он соответствует региону и языку Oracle.