Я хочу написать код, действительный как для float, так и для двойной точности. я делаю что-то вроде этого:float (0.0) vs 0.0f в CUDA
typedef real float;
//typedef real double;
__global__ void foo(real a, real *b){
b[0] = real(0.5)*a;
}
int main(){
real a = 1.0f;
real *b;
cudaMalloc(&f, sizeof(real));
foo<<<1,1>>>(a,b);
return 0;
}
Это заставило меня думать, я не хочу потерять точность в постоянной, как 0.5f при выполнении двойной точности, но я не хочу, чтобы способствовать 0,5 удвоить делая одиночная точность!
Итак, я использовал оператор real(), как в примере. В режиме одиночной точности, если я разобрал функцию «foo» с помощью real (0.5), я понял, что нет поощрения удвоения, в отличие от использования всего 0,5, когда продвижение происходит.
Вы можете проверить с помощью:
$nvcc test.cu -arch=sm_52 -lineinfo --source-in-ptx -g -G -O0 ; cuobjdump -sass a.out | grep "foo" -A 35
Я вижу
/*0078*/ FMUL R0, R0, 0.5; /* 0x3868004000070000 */
При использовании реальной (0.5) или 0.5f И:
/*0078*/ F2F.F64.F32 R4, R0; /* 0x5ca8000000070b04 */
/*0088*/ DMUL R4, R4, 0.5; /* 0x3880004000070404 */
/*0090*/ F2F.F32.F64 R0, R4; /* 0x5ca8000000470e00 */
При написании всего 0,5.
Это может показаться чересчур очевидным. Но поскольку я не знаю, что такое «реальный (0,5)», я не знаю, является ли это только компилятором, играющим в этом конкретном случае. Разборный код кажется идентичным как в реальных (0,5), так и в 0,5f!
Так что вопрос остается:
Что реально (0,5) (AKA поплавок (0,5)) на самом деле?
Есть ли разница между поплавком (0,5) и 0,5f? (OR double (0,5) и 0,5)
Это также относится к C/C++, я полагаю.
От ссылки: 1) Если есть неявная последовательность преобразований из выражения в new_type или если разрешение перегрузки для прямой инициализации объекта или ссылки типа new_type из выражения найдет хотя бы одну жизнеспособную функцию, тогда static_cast (выражение) возвращает мнимую переменную Temp, инициализированную так, как если бы она была создана с помощью new_type Temp (expression) ;, которая может включать неявные преобразования, вызов конструктора new_type или вызов пользовательского оператора преобразования. –
Apo
Разве это не означает, что static_cast (0.5) вызывает real (0.5)? Кроме того, [static_cast] может включать неявные преобразования, вызов конструктора new_type или вызов пользовательского оператора преобразования. ". Итак, это что-то делает во время выполнения, а не в 0,5f? –
Apo
Если у вас были более сложные типы (с конструктором), то это могло бы быть. В вашем случае, однако, вы можете легко увидеть, что ничего подобного не происходит. Вы инициализируете 'real' со значением' 0,5'. Компилятор знает, как это сделать во время компиляции, а затем он не вынужден генерировать продвижение в два раза для выполнения умножения. – krzaq